[SCOI2011]糖果

[SCOI2011]糖果
題目描述
幼兒園裏有N個小朋友,lxhgww老師現在想要給這些小朋友們分配糖果,要求每個小朋友都要分到糖果。但是小朋友們也有嫉妒心,總是會提出一些要求,比如小明不希望小紅分到的糖果比他的多,於是在分配糖果的時候,lxhgww需要滿足小朋友們的K個要求。幼兒園的糖果總是有限的,lxhgww想知道他至少需要準備多少個糖果,才能使得每個小朋友都能夠分到糖果,並且滿足小朋友們所有的要求。
輸入輸出格式
輸入格式:
輸入的第一行是兩個整數N,K。接下來K行,表示這些點需要滿足的關係,每行3個數字,X,A,B。如果X=1, 表示第A個小朋友分到的糖果必須和第B個小朋友分到的糖果一樣多;如果X=2, 表示第A個小朋友分到的糖果必須少於第B個小朋友分到的糖果;如果X=3, 表示第A個小朋友分到的糖果必須不少於第B個小朋友分到的糖果;如果X=4, 表示第A個小朋友分到的糖果必須多於第B個小朋友分到的糖果;如果X=5, 表示第A個小朋友分到的糖果必須不多於第B個小朋友分到的糖果;
輸出格式:
輸出一行,表示lxhgww老師至少需要準備的糖果數,如果不能滿足小朋友們的所有要求,就輸出-1。
輸入輸出樣例
輸入樣例#1:
5 71 1 22 3 24 4 13 4 55 4 52 3 54 5 1
輸出樣例#1:
11
說明
【數據範圍】
對於30%的數據,保證 N<=100
對於100%的數據,保證 N<=100000
對於所有的數據,保證 K<=100000,1<=X<=5,1<=A, B<=N

題解:
差分約束題目,1操作看出a-b>=0 &&b-a>=0,所以a和b互相連一條權值爲0的邊。
2操作看成b-a>=1從a向b連一條長度爲1的邊,3看成a-b>=1,4看成a-b>=1,5看成b-a>=0求最長路。

代碼:
#include<bits/stdc++.h>
#define LL long long
using namespace std;

const LL max_n = 100001;
const LL inf = 1e9+7;

LL point[max_n],nxt[max_n<<1],v[max_n<<1],w[max_n<<1];
LL dis[max_n];
bool vis[max_n];
queue<LL> q;
LL n,k,x,y,c,tot,ans;

inline void init()
{
	memset(point,-1,sizeof(point));
	memset(nxt,-1,sizeof(nxt));
	tot=-1;
}

inline void addedge(LL x,LL y,LL val)
{
	++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y; w[tot]=val;
}

inline bool spfa()
{
	while(!q.empty())
	{
		LL now=q.front(); q.pop();
		if(dis[now]>n) return true;
		for(LL i=point[now]; i!=-1; i=nxt[i])
		  if(dis[now]+w[i]>dis[v[i]])
		  {
		  	dis[v[i]]=dis[now]+w[i];
		  	if(!vis[v[i]]) q.push(v[i]);
		  	vis[v[i]]=true;
		  }
		vis[now]=false;
	}
	return false;
}

int main()
{
	scanf("%lld%lld",&n,&k);
	init();
	for(LL i=1; i<=k; ++i)
	{
		scanf("%lld%lld%lld",&c,&x,&y);
		if(c==1) addedge(x,y,0),addedge(y,x,0);
		else if(c==2) addedge(x,y,1);
		else if(c==3) addedge(y,x,0);
		else if(c==4) addedge(y,x,1);
		else addedge(x,y,0);
		if((c==2 || c==4) && x==y)
		{
			printf("-1\n");
			return 0;
		}
	}
	for(LL i=1; i<=n; ++i)
	{
		q.push(i);
		dis[i]=1;
		vis[i]=true;
	}
	if(spfa())
	{
		printf("-1\n");
		return 0;
	}
	for(LL i=1; i<=n; ++i)
	  ans+=dis[i];
	printf("%lld\n",ans);
	return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章