洛谷2294 & BZOJ1202:[HNOI2005]狡猾的商人——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=1202
https://www.luogu.com.cn/problem/P2294
***姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的。账本上记录了n个月以来的收入情况,其中第i 个月的收入额为Ai(i=1,2,3...n-1,n), 。当 Ai大于0时表示这个月盈利Ai 元,当 Ai小于0时表示这个月亏损Ai 元。所谓一段时间内的总收入,就是这段时间内每个月的收入额的总和。 ***姹的任务是秘密进行的,为了调查商人的账本,她只好跑到商人那里打工。她趁商人不在时去偷看账本,可是她无法将账本偷出来,每次偷看账本时她都只能看某段时间内账本上记录的收入情况,并且她只能记住这段时间内的总收入。 现在,***姹总共偷看了m次账本,当然也就记住了m段时间内的总收入,你的任务是根据记住的这些信息来判断账本是不是假的。
查差分约束词条出来的题,然而显然用带权并查集更简单……思想僵化。
把给出的操作看做差分,然后就变成了m个等式了,套差分约束,就做完了。
#include<cmath> #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N=105; const int M=5005; const int INF=1e9; inline int read(){ int X=0,w=0;char ch=0; while(!isdigit(ch)){w|=ch=='-';ch=getchar();} while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X; } struct node{ int w,to,nxt; }e[M]; int n,m,cnt,head[N],dis[N],sum[N]; bool vis[N]; inline void add(int u,int v,int w){ e[++cnt].to=v;e[cnt].w=w;e[cnt].nxt=head[u];head[u]=cnt; } queue<int>q; bool spfa(int s){ for(int i=0;i<=n+1;i++)dis[i]=INF,sum[i]=0; q.push(s);vis[s]=1;dis[s]=0;sum[s]++; while(!q.empty()){ int u=q.front();q.pop();vis[u]=0; for(int i=head[u];i;i=e[i].nxt){ int v=e[i].to,w=e[i].w; if(dis[v]-w>dis[u]){ dis[v]=dis[u]+w; if(!vis[v]){ if(++sum[v]>=n+2)return 0; q.push(v);vis[v]=1; } } } } return 1; } void init(){ cnt=0; memset(vis,0,sizeof(vis)); memset(head,0,sizeof(head)); } int main(){ int T=read(); while(T--){ init(); n=read(),m=read(); int s=n+1; for(int i=0;i<=n;i++)add(s,i,0); for(int i=1;i<=m;i++){ int u=read()-1,v=read(),w=read(); add(u,v,w);add(v,u,-w); } if(!spfa(s))puts("false"); else puts("true"); } return 0; }
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++