差分约束系统,a到b有一条长度为c的边,表示b至多比a多c。
那么对于操作1,a比b多至少c,等价于b比a多至多-c。
然后矛盾的情况就是,a比a多至多<0,即存在负环,记得跑最短路。
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #define inf 0x7fffffff #define maxn 10010 using namespace std; int next[maxn],head[maxn],to[maxn],len[maxn]; int dis[maxn]; int n,m,num,flag=0; bool vis[maxn]; void spfa(int x) { vis[x]=1; for (int p=head[x];p;p=next[p]) if (dis[to[p]]>dis[x]+len[p]) { if (vis[to[p]]) { flag=1; break; } dis[to[p]]=dis[x]+len[p]; spfa(to[p]); } vis[x]=0; } void addedge(int x,int y,int z) { num++;to[num]=y;len[num]=z;next[num]=head[x];head[x]=num; } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) { int op,x,y,z; scanf("%d%d%d",&op,&x,&y); if (op==1) { scanf("%d",&z); addedge(x,y,-z); } if (op==2) { scanf("%d",&z); addedge(y,x,z); } if (op==3) addedge(x,y,0); } for (int i=1;i<=n;i++) { dis[i]=0; spfa(i); } if (flag) printf("No\n"); else printf("Yes\n"); return 0; }