[SCOI2011]糖果

题目

bzoj2330

题解

裸的差分约束......

也许是因为太裸了,用(sàng)心(xīn)良(bìng)苦(kuáng)的出题人竟然卡spfa,某数据点有一条长为十万的链……

倒着连边

代码

include

include

include

include

include

include

include

define N 500050

define inf 10000000000

define ll long long

using namespace std;

int n,k;
ll ans;

int num,a[N],b[N],w[N],nt[N],p[N];
void add(int x,int y,int v)
{
a[++num]=x;b[num]=y;w[num]=v;
nt[num]=p[x];p[x]=num;
}

int flag[N],cnt[N],f;queue q;ll dis[N];
void spfa()
{
for(int i=1;i<=n;i++) dis[i]=-inf;
q.push(0);flag[0]=1;dis[0]=0;cnt[0]++;
while(!q.empty())
{
int k=q.front();q.pop();
for(int e=p[k];e;e=nt[e])
{
int kk=b[e];
if(dis[kk]<dis[k]+w[e])
{
dis[kk]=dis[k]+w[e];
if(!flag[kk]) {flag[kk]=1;q.push(kk);cnt[kk]++;}
if(cnt[kk]>n) {f=1;break;}
}
}
flag[k]=0;
if(f) break;
}
}

int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=k;i++)
{
int opt,x,y;scanf("%d%d%d",&opt,&x,&y);
if(opt1) add(x,y,0),add(y,x,0);
else if(opt
2) {if(xy){printf("-1");return 0;}add(x,y,1);}
else if(opt
3) add(y,x,0);
else if(opt4) {if(xy){printf("-1");return 0;}add(y,x,1);}
else add(x,y,0);
}
for(int i=n;i>=1;i--) add(0,i,1);
spfa();
if(f) printf("-1");
else
{
for(int i=1;i<=n;i++) ans+=dis[i];
printf("%lld",ans);
}
return 0;
}

posted @ 2017-08-23 11:04  XYZinc  阅读(248)  评论(0)    收藏  举报