码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 2330 [SCOI2011]糖果

时间:2018-03-03 20:32:10      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:long   empty   amp   ring   name   scoi2011   else   约束   print   

题解:差分约束

怎么才可以卡掉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;
}

  

 

BZOJ 2330 [SCOI2011]糖果

标签:long   empty   amp   ring   name   scoi2011   else   约束   print   

原文地址:https://www.cnblogs.com/zzyer/p/8502697.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!