题解:差分约束
怎么才可以卡掉Spfa与正反向建边的关系
在不T的情况下要多入队几次才能判出负环
出题人SangxinBingkuang
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; typedef long long Lint; const Lint oo=10000000000000; const int maxn=300009; int n,m; long long ans=0; int cntedge=0; int head[maxn]={0}; int to[maxn<<1]={0},nex[maxn<<1]={0}; Lint dist[maxn<<1]={0}; void Addedge(int x,int y,Lint z){ nex[++cntedge]=head[x]; to[cntedge]=y; dist[cntedge]=z; head[x]=cntedge; } int s; queue<int>q; int inq[maxn]={0}; Lint d[maxn]; int t[maxn]; int Spfa(){ for(int i=1;i<=n;++i)d[i]=-oo; d[s]=0;inq[s]=1;q.push(s); while(!q.empty()){ int x=q.front();q.pop();inq[x]=0; for(int i=head[x];i;i=nex[i]){ if(d[x]+dist[i]>d[to[i]]){ d[to[i]]=d[x]+dist[i]; if(!inq[to[i]]){ if(++t[to[i]]==500)return 0; q.push(to[i]); inq[to[i]]=1; } } } } return 1; } int main(){ scanf("%d%d",&n,&m); s=n+1; while(m--){ int opty,x,y; scanf("%d%d%d",&opty,&x,&y); if(opty==1){ Addedge(x,y,0); Addedge(y,x,0); } if(opty==2){ Addedge(x,y,1); } if(opty==3){ Addedge(y,x,0); } if(opty==4){ Addedge(y,x,1); } if(opty==5){ Addedge(x,y,0); } } for(int i=n;i>=1;--i)Addedge(s,i,1); if(!Spfa()){ printf("-1\n"); return 0; }else{ for(int i=1;i<=n;++i)ans+=d[i]; printf("%lld\n",ans); } return 0; }