差分约束基础,对于每种关系建不同的边,求是否有负环。
code:
/************************************************************** Problem: 3436 User: yekehe Language: C++ Result: Accepted Time:252 ms Memory:10916 kb ****************************************************************/ #include <cstdio> #include <vector> #include <cstring> using namespace std; char tc() { static char fl[10000000],*A=fl,*B=fl; return A==B&&(B=(A=fl)+fread(fl,1,10000000,stdin),A==B)?EOF:*A++; } int read() { char c;while(c=getchar(),(c<'0' || c>'9') && c!='-'); int x=0,y=1;c=='-'?y=-1:x=c-'0'; while(c=getchar(),c>='0' && c<='9')x=x*10+c-'0';return x*y; } const int MAXN=10005; int N,M; int o,x,y,z; int dist[MAXN],vis[MAXN]; bool flag; vector < pair<int, int> > a[MAXN]; void cf_spfa(int x) { int to,val; for(int i=0;i<a[x].size();i++){ to=a[x][i].first;val=a[x][i].second; if(dist[x]+val<dist[to]){ if(vis[to]){ flag=true; return ; } else { dist[to]=dist[x]+val; vis[to]=1; cf_spfa(to); } } } vis[x]=false; }//SPFA判负环 int main() { // freopen("x.txt","r",stdin); N=read(),M=read(); for(int i=1; i<=M; i++){ o=read(); if(o==1) {x=read(),y=read(),z=read();a[y].push_back(make_pair(x,-z));} if(o==2) {x=read(),y=read(),z=read();a[x].push_back(make_pair(y,z));} if(o==3) {x=read(),y=read();a[x].push_back(make_pair(y,0)),a[y].push_back(make_pair(x,0));} }//建边 for(int i=1; i<=N; i++) {memset(dist,0,sizeof(dist));cf_spfa(i);if(flag)break;} if(flag)puts("No"); else puts("Yes"); return 0; }