BZOJ2330 [SCOI2011]糖果 差分约束模板

很久以前学的差分约束,基本忘了,复习一下

a<=b+c,ins(b,a,c)是最短链,每个元素最大

a>=b+c,ins(b,a,c)是最长链,每个元素最小

#include<bits/stdc++.h>  
#pragma comment(linker, "/STACK:1024000000,1024000000")   
#include<stdio.h>  
#include<algorithm>  
#include<queue>  
#include<string.h>  
#include<iostream>  
#include<math.h>  
#include<set>  
#include<map>  
#include<vector>  
#include<iomanip>  
using namespace std;  
#define ll long long  
#define pb push_back  
#define FOR(a) for(int i=1;i<=a;i++)  
const int inf=0x3f3f3f3f;  
 
const int maxn=1e5+5;    
 
int n,m,s;

struct EDGE{int v,ne;double w;}e[maxn<<1];
int h[maxn],cnt=0;
inline void ins(int u,int v,int w){
	cnt++;
	e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;
}
int q[maxn],head,tail,inq[maxn],num[maxn],d[maxn];
inline void lop(int &x){if(x==maxn)x=1;}
bool spfa(int s){
	for(int i=1;i<=n;i++)d[i]=-inf;
	head=tail=0;
	memset(inq,0,sizeof inq);
	memset(num,0,sizeof num);
	for(int i=1;i<=n;i++)q[tail++]=i,inq[i]=1,d[i]=1;
	while(head!=tail){
		int u=q[head++];inq[u]=0;lop(head);
		for(int i=h[u];i;i=e[i].ne){
			int v=e[i].v,w=e[i].w;
			if(d[v]<d[u]+w){
				d[v]=d[u]+w;
				if(!inq[v]){
					inq[v]=1,q[tail++]=v,lop(tail);
					if(++num[v]>n)return 1;
				}
			}
		}
	}
	return 0;
}

int main(){
	scanf("%d%d",&n,&m);
	s=0;
	for(int i=1,x,a,b;i<=m;i++){
		scanf("%d%d%d",&x,&a,&b);
		if(x==1)ins(a,b,0),ins(b,a,0);
		else if(x==2){if(a==b){puts("-1");return 0;}ins(a,b,1);}
		else if(x==3){ins(b,a,0);}
		else if(x==4){if(a==b){puts("-1");return 0;}ins(b,a,1);}
		else ins(a,b,0);
	}
	if(spfa(s))puts("-1");
	else{
		ll ans=0;
		for(int i=1;i<=n;i++)ans+=d[i];
		printf("%lld\n",ans);
	}
}


posted @ 2017-12-02 08:44  Drenight  阅读(122)  评论(0编辑  收藏  举报