P3275 [SCOI2011]糖果
调了好久的差分约束,话说倒序加边真的玄学
#include<bits/stdc++.h> using namespace std; const int bow=100010; int n,m,a,b,c,ne,head[bow],vist[bow],usd[bow<<2],d[bow]; struct node{int nxt,to,dis;}eg[bow<<2]; void adde(int u,int v,int val){eg[++ne].nxt=head[u];eg[ne].to=v;eg[ne].dis=val;head[u]=ne;} int spfa(){ queue<int>q; q.push(0);d[0]=0;vist[0]=1; while(!q.empty()){ int u=q.front(); q.pop();vist[u]=0; for(int i=head[u];i;i=eg[i].nxt) if(d[eg[i].to]<d[u]+eg[i].dis){ d[eg[i].to]=d[u]+eg[i].dis;usd[i]++;if(usd[i]>n-1)return 0; if(!vist[eg[i].to]){vist[eg[i].to]=1;q.push(eg[i].to);} } } return 1; } int main() { cin>>n>>m; int flg=0; while(m--) { scanf("%d%d%d",&c,&a,&b); if(c==1){adde(a,b,0);adde(b,a,0);} if(c==2)adde(a,b,1); if(c==3)adde(b,a,0); if(c==4)adde(b,a,1); if(c==5)adde(a,b,0); if(c%2==0&&a==b)flg=1; } if(flg==1){cout<<-1;return 0;} for(int i=n;i>=1;i--)adde(0,i,1); if(!spfa())cout<<-1; else{ long long ans=0; for(int i=1;i<=n;i++)ans+=d[i]; cout<<ans; } }