BZOJ1202 [HNOI2005] 狡猾的商人
「BZOJ1202」[HNOI2005] 狡猾的商人
Description
Input
Output
Sample Input
3 3
1 2 10
1 3 -5
3 3 -15
5 3
1 5 100
3 5 50
1 2 51
Sample Output
false
一、差分约束系统
其实这道题如果用差分约束来写的话,不是特别难,它用了一个非常常用的思想:前缀和(类似于种树那道题),因为输入的账单是区间形式的,所以直接记录成前缀和,建双向边跑一边最长路,当存在正环的时候,就不合法了。
1 #include<stdio.h> 2 #include<string.h> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 const int inf=1e9+7; 7 template<class T>void read(T &x) 8 { 9 int f=0;x=0;char ch=getchar(); 10 while(ch<'0'||ch>'9') {f|=(ch=='-');ch=getchar();} 11 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} 12 x=f?-x:x; 13 } 14 struct Edge{ 15 int v,w,next; 16 }e[7007]; 17 int head[7007],n,m,T,s,t,v,tot,d[1007],Tot[1007]; 18 bool vis[1007],flag; 19 void add(int u,int v,int w) 20 { 21 e[++tot].v=v; 22 e[tot].w=w; 23 e[tot].next=head[u]; 24 head[u]=tot; 25 } 26 bool spfa(int s) 27 { 28 for(int i=1;i<=n;++i) 29 d[i]=-inf; 30 queue<int> qwq; 31 qwq.push(s); 32 d[s]=0;vis[s]=1; 33 while(!qwq.empty()) 34 { 35 int u=qwq.front(); 36 qwq.pop(); 37 vis[u]=0; 38 if(++Tot[u]>n) return 0; 39 for(int i=head[u];i;i=e[i].next) 40 { 41 int v=e[i].v,w=e[i].w; 42 if(d[v]<d[u]+w) 43 { 44 d[v]=d[u]+w; 45 if(!vis[v]) 46 { 47 vis[v]=1; 48 qwq.push(v); 49 } 50 } 51 } 52 } 53 return 1; 54 } 55 int main() 56 { 57 read(T); 58 while(T--) 59 { 60 flag=0;tot=0; 61 memset(vis,0,sizeof(vis)); 62 memset(Tot,0,sizeof(Tot)); 63 memset(head,0,sizeof(head)); 64 read(n),read(m); 65 for(int i=1;i<=m;++i) 66 { 67 read(s),read(t),read(v); 68 add(s-1,t,v),add(t,s-1,-v); 69 } 70 for(int i=0;i<=n;++i) 71 if(!Tot[i]) 72 if(!spfa(i)) 73 {printf("false\n"),flag=1;break;} 74 if(!flag) printf("true\n"); 75 } 76 return 0; 77 }
二、带权并查集
同样的,题目给出了区间就用前缀和来写:如果知道sum(a,b)、sum(b,c),那我们只需要知道一组sun(a,c)便可以验证账本的真假了;所以用并查集维护点对(l,r),用一个前缀和数组维护权值w,每次输入点对(l,r)时,判断是否在并查集中,如果在就直接用前缀和查询是否合法,否则加入并查集;
PS:带权并查集必须用递归实现,否则会咕咕咕???
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 template<class T>void read(T &x) 6 { 7 int f=0;x=0;char ch=getchar(); 8 while(ch<'0'||ch>'9') {f|=(ch=='-');ch=getchar();} 9 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} 10 x=f?-x:x; 11 } 12 int fa[107],cha[107],m,n,l,r,w,T; 13 14 int find(int x) 15 { 16 int xx=x,t; 17 while(fa[x]!=x) x=fa[x],cha[x]+=cha[fa[x]]; 18 while(xx!=x) 19 { 20 t=fa[xx]; 21 fa[xx]=x; 22 xx=t; 23 } 24 return x; 25 }/* 26 int find(int x) 27 { 28 if(x!=fa[x]) 29 { 30 int t=find(fa[x]); 31 cha[x]+=cha[fa[x]]; 32 fa[x]=t; 33 } 34 return fa[x]; 35 } */ 36 int main() 37 { 38 read(T); 39 while(T--) 40 { 41 bool flag=0; 42 read(n),read(m); 43 for(int i=0;i<=n;++i) 44 fa[i]=i,cha[i]=0; 45 for(int i=1;i<=m;++i) 46 { 47 read(l),read(r),read(w); 48 --l; 49 if(find(l)!=find(r)) 50 { 51 cha[fa[r]]=cha[l]-cha[r]-w; 52 fa[fa[r]]=fa[l]; 53 } 54 else if(cha[l]-cha[r]!=w) {printf("false\n");flag=1;break;} 55 } 56 if(!flag) printf("true\n"); 57 } 58 }
三、总结
这道题可以用以上两种解法来解决,但是各有特点
差分:时间较慢、代码量较大,但容易想到而且代码实现相对简单。
并查集:时间很快、代码量很小,但是相对不太容易想到思路
共同点:核心都是用了前缀和的思想,所以说前缀和(差分数组)虽然思想简单,但还是挺重要的一个内容,所以多做多练练吧
转载于:https://www.cnblogs.com/Peper/p/9623827.html
BZOJ1202 [HNOI2005] 狡猾的商人相关推荐
- bzoj1202[HNOI2005]狡猾的商人
bzoj1202[HNOI2005]狡猾的商人 题意: 账本上记录了n个月以来的收入情况,其中第i 个月的收入额为Ai .所谓一段时间内的总收入,就是这段时间内每个月的收入额的总和.给出m段时间内的总 ...
- BZOJ1202 [HNOI2005]狡猾的商人 【并查集】
1202: [HNOI2005]狡猾的商人 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 4180 Solved: 2015 [Submit][S ...
- BZOJ1202: [HNOI2005]狡猾的商人
Description 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的.账本上记录了n个月以来的收入情况,其中第i 个月的收入额为Ai(i=1,2,3...n-1,n), .当 ...
- BZOJ1202 [HNOI2005]狡猾的商人(洛谷P2294)
带权并查集 BZOJ题目传送门 洛谷题目传送门 之前做过几乎一样的题目(这里),然而忘光了 记wiwiw_i表示根节点到iii这段时间的盈利,当x" role="presentat ...
- bzoj1202 [HNOI2005]狡猾的商人
https://www.lydsy.com/JudgeOnline/problem.php?id=1202 带权并查集维护前缀和 s,t,v相当于sum[t]-sum[s-1]=v,那么对于一个连通块 ...
- 1202: [HNOI2005]狡猾的商人
1202: [HNOI2005]狡猾的商人 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 1554 Solved: 745 [Submit][St ...
- P2294 [HNOI2005]狡猾的商人
P2294 [HNOI2005]狡猾的商人 题意: 你需要调查某个商人的账本,给你n个月内,m条账单信息,每条账单信息为x到y月的收入或者支出多少钱,问你根据账单信息判断这个账本是否合理 5 3 1 ...
- bzoj 1202: [HNOI2005]狡猾的商人(带权并查集)
1202: [HNOI2005]狡猾的商人 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 3616 Solved: 1740 [Submit][S ...
- 洛谷 P2294 [HNOI2005]狡猾的商人
洛谷 P2294 [HNOI2005]狡猾的商人 题目: 有图·.转链接 题解: 差分约束. 虽然题目中没有出现不等式,但还是属于差分约束的范畴之内的. 一开始我就按照它的要求u到v加权值w的边.但发 ...
- [HNOI2005]狡猾的商人
[HNOI2005]狡猾的商人 Time Limit: 10 Sec Memory Limit: 162 MB Description 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪 ...
最新文章
- python全栈 day09随笔
- 【C 语言】内存四区原理 ( 栈内存与堆内存对比示例 | 函数返回的堆内存指针 | 函数返回的栈内存指针 )
- 设计模式理解:模板方法
- Mybatis的jdbc参数设置
- 判断给定的二叉树是否为二叉排序树
- bash shell数组模拟队列queue和shell数组使用技巧
- 2020年高考数学试题难吗?历史上最难数学卷不是2003!
- 阿里云设置域名解析到主机ip
- SKYLINE UVALive - 4108
- 如何生成漫画风图片无需下载APP无需PS无需电脑
- 3dmax shift用来复制对象
- linux下apache+php配置
- MATLAB常见问题:小数保留有效数字位数相关问题/除法结果问题/数据显示格式设置
- Cuba Platform Introduce (Cuba平台介绍)
- plsql 快捷键 设置 字母大小写
- bat批处理与adb命令的配合
- 阿里云相关——高速通道
- VUE实现登录和登出
- Android自定义控件之圆形头像
- 消息队列MQ/JMS/Kafka,你都了解吗?