题解:
查分约数系统
1情况:x->y 建立条-z
2情况:y->x 建一条z
3情况:x->y建一条0
然后0对于每一个点见一个0
跑一下最短路,看是否又负环
代码:
#include<bits/stdc++.h> using namespace std; const int N=1e5+5; int n,m,pd,x,b[N*10],dis[N],f[N],cost[N],num,sl[N],y,z,fi[N],ne[N],zz[N]; void jb(int x,int y,int z) { ne[++num]=fi[x]; fi[x]=num; zz[num]=y; sl[num]=z; } int main() { scanf("%d%d",&n,&m); while (m--) { scanf("%d",&pd); if (pd==1) { scanf("%d%d%d",&x,&y,&z); jb(x,y,-z); } if (pd==2) { scanf("%d%d%d",&x,&y,&z); jb(y,x,z); } if (pd==3) { scanf("%d%d",&x,&y); jb(x,y,0); } } int l=0,r=1; f[0]=cost[0]=1; memset(dis,0x3f,sizeof dis); dis[0]=0; for (int i=1;i<=n;i++)jb(0,i,0); while (l!=r) { int num=b[l++]; l%=(N*10); f[num]=0; for (int i=fi[num];i;i=ne[i]) { int t=zz[i]; if (dis[t]>dis[num]+sl[i]) { dis[t]=dis[num]+sl[i]; if (!f[t]) { f[t]=1; b[r++]=t; r%=(N*10); cost[t]++; if (cost[t]>=n) { puts("No"); return 0; } } } } } puts("Yes"); return 0; }