图论 差分约束scoi 2011 糖果

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/Stevencwehf/article/details/102658627

[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个小朋友分到的糖果;
样例输入
6 3
1 6 2 5 3 4
0 1 4
1 3 6
0 2 4
3
样例输出
11

思路 差分约束系统 但注意这道题只能用最长路

在这里插入图片描述
如1号点 它要满足两组约束条件 但是只能用最长的那条(3->2->1)

#include<bits/stdc++.h>
using namespace std;
#define int  long long 
inline int read()
{
    int data=0;int w=1; char ch=0;
    ch=getchar();
    while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
    if(ch=='-') w=-1,ch=getchar();
    while(ch>='0' && ch<='9') data=(data<<3)+(data<<1)+ch-'0',ch=getchar();
    return data*w;
}
const int N=400000;
int n,k;
struct edge{
	int v,w,nxt;
}e[N<<1];
int fir[N],cnt=0;
inline void add(int u,int v,int w){e[++cnt]=(edge){v,w,fir[u]}; fir[u]=cnt;}
queue<int>q;
int vis[N],dis[N],vi[N];
inline int spfa(){
    vis[0]=1;dis[0]=0;vi[0]=1;
    q.push(0);
    while(!q.empty()){
    	int u=q.front();q.pop();vi[u]=0;
    	for(int i=fir[u];i;i=e[i].nxt){
    		int v=e[i].v,w=e[i].w;
    		if(dis[v]<dis[u]+w){
    		    dis[v]=dis[u]+w;
    		    if(!vi[v]){
    		    	if(++vis[v]==n) return 0;
    		        q.push(v);vi[v]=1;
				}
			}
		}
	}
	return 1;
}
signed main(){
	n=read();k=read();
	int ans=0;	
	for(int i=n;i>=1;i--){add(0,i,1);}
    while(k--){
    	int x=read(),a=read(),b=read();
    	switch(x){
    		case 1:add(a,b,0),add(b,a,0);break;
    		case 2:if(a==b){cout<<-1;return 0;}
			add(a,b,1);break;
    		case 3:add(b,a,0);break;
    		case 4:	if(a==b){cout<<-1;return 0;}
			add(b,a,1);break;
    		case 5:add(a,b,0);break;
		}
	}
    if(!spfa()) {
     	printf("-1");return 0;
	 }
	for(int i=1;i<=n;i++){ans+=dis[i];}
     printf("%lld",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Stevencwehf/article/details/102658627
今日推荐