1. 程式人生 > >洛谷P3275 [SCOI2011]糖果_差分約束_判負環

洛谷P3275 [SCOI2011]糖果_差分約束_判負環

Code:

#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
const int N=300000+3;
const int INF=-2333233;
queue<int>Q;
int d[N],inq[N],times[N];
int head[N],to[N<<1],val[N<<1],nex[N<<1];
int cnt,n,s,k;
void add_edge(int u,int v,int c)
{
    nex[
++cnt]=head[u],head[u]=cnt; to[cnt]=v,val[cnt]=c; } int spfa() { for(int i=1;i<=n;++i) d[i]=INF; d[s]=0,inq[s]=1;Q.push(s); while(!Q.empty()) { int u=Q.front();Q.pop();inq[u]=0; ++times[u]; if(times[u]>=n)return 0; for(int v=head[u];v;v=nex[v]
) if(d[to[v]]<d[u]+val[v]) { d[to[v]]=d[u]+val[v]; if(!inq[to[v]]) { inq[to[v]]=1; Q.push(to[v]); } } } return 1; } int main() { scanf("%d%d",&n,&k); for(int i=1;i<=k;++i) { int
Ty,a,b; scanf("%d%d%d",&Ty,&a,&b); if(Ty==1){ add_edge(b,a,0); add_edge(a,b,0); } if(Ty==2) add_edge(a,b,1); if(Ty==3) add_edge(b,a,0); if(Ty==4) add_edge(b,a,1); if(Ty==5) add_edge(a,b,0); if(Ty%2==0&&a==b) { printf("-1");return 0; } } s=0; for(int i=n;i>=1;--i)add_edge(s,i,1); if(!spfa()) { printf("-1");return 0; } long long ans=0; for(int i=1;i<=n;++i)ans+=d[i]; printf("%lld",ans); return 0; }