题解:
差分约束系统
要我们求最小值
显然就是转化为最长路
然后spfa一下即可
代码:
#include<bits/stdc++.h> using namespace std; const int N=400005; long long ans,dis[N]; int n,m,op,x,y,sl[N],Q[N],flag[N],tot,zz[N],fi[N],ne[N],num[N]; void jb(int x,int y,int z) { ne[++tot]=fi[x]; fi[x]=tot; zz[tot]=y; sl[tot]=z; } int main() { scanf("%d%d",&n,&m); while (m--) { scanf("%d%d%d",&op,&x,&y); if (op==1) { jb(x,y,0); jb(y,x,0); } if (op==2) if (x==y) { puts("-1"); return 0; } else jb(x,y,1); if (op==3)jb(y,x,0); if (op==4) if (x==y) { puts("-1"); return 0; } else jb(y,x,1); if (op==5)jb(x,y,0); } for (int i=1;i<=n;i++)jb(0,n-i+1,1); int l=0,r=1; while (l!=r) { int now=Q[l++]; if (l==N)l=0; flag[now]=0; for (int i=fi[now];i;i=ne[i]) { if (dis[zz[i]]<dis[now]+sl[i]) { dis[zz[i]]=dis[now]+sl[i]; if (!flag[zz[i]]) { flag[zz[i]]=1; if (++num[zz[i]]>=n) { puts("-1"); return 0; } Q[r++]=zz[i]; if (r==N)r=0; } } } } for (int i=1;i<=n;i++)ans+=dis[i]; printf("%lld",ans); }