2330: [SCOI2011]糖果
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 7058 Solved: 2387
[Submit][Status][Discuss]
Description
幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果。但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的多,于是在分配糖果的时候,lxhgww需要满足小朋友们的K个要求。幼儿园的糖果总是有限的,lxhgww想知道他至少需要准备多少个糖果,才能使得每个小朋友都能够分到糖果,并且满足小朋友们所有的要求。
Input
输入的第一行是两个整数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个小朋友分到的糖果;
Output
输出一行,表示lxhgww老师至少需要准备的糖果数,如果不能满足小朋友们的所有要求,就输出-1。
Sample Input
5 7
1 1 2
2 3 2
4 4 1
3 4 5
5 4 5
2 3 5
4 5 1
1 1 2
2 3 2
4 4 1
3 4 5
5 4 5
2 3 5
4 5 1
Sample Output
11
HINT
【数据范围】
对于30%的数据,保证 N<=100
对于100%的数据,保证 N<=100000
对于所有的数据,保证 K<=100000,1<=X<=5,1<=A, B<=N
Source
这是一道差分约束的水题
根据题目要求进行建图
x=1时 A到B连一条边权为0的双向边
x=2时 A到B连一条边权为1的单向边
x=3时 B到A连一条边权为0的单向边
x=4时 B到A连一条边权为1的单向边
x=5时 A到B连一条边权为0的单向边
依据条件跑最短路即可
#include <bits/stdc++.h> #define ll long long #define eps 1e-7 #define inf 100000000 using namespace std; inline int read(){ int x=0;int f=1;char ch=getchar(); while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} return x*f; } const int MAXN=1e6+10; namespace zhangenming{ struct node{ int y; int v; int next; }e[MAXN*2]; int len=0; int linkk[MAXN*2],q[MAXN<<1],dis[MAXN],cnt[MAXN],n,k; bool vis[MAXN]={}; inline void insert(int xx,int yy,int vv) { e[++len].y=yy; e[len].next=linkk[xx]; e[len].v=vv;linkk[xx]=len; } void init(){ n=read();k=read(); for(int i=1;i<=k;i++){ int x=read(); int xx=read(); int yy=read(); if(x==1) {insert(xx,yy,0);insert(yy,xx,0);} if(x==2) {insert(xx,yy,1);} if(x==3) insert(yy,xx,0); if(x==4) insert(yy,xx,1); if(x==5) insert(xx,yy,0); if(x%2==0&&xx==yy) {cout<<-1<<endl;exit(0);} } for(int i=n;i>=1;i--){ insert(0,i,1); } } void spfa(){ int head=0;int tail=0; q[++tail]=0; vis[0]=0; memset(dis,-10,sizeof(dis)); dis[0]=0; while(head<tail){ int tn=q[++head]; for(int i=linkk[tn];i;i=e[i].next){ if(dis[e[i].y]<dis[tn]+e[i].v){ dis[e[i].y]=dis[tn]+e[i].v; if(!vis[e[i].y]){ if(cnt[e[i].y]==n){cout<<-1<<endl;exit(0);} q[++tail]=e[i].y; cnt[e[i].y]++; vis[e[i].y]=true; } } } vis[tn]=false; } } void put(){ long long int ans=0; for(int i=1;i<=n;i++){ ans+=dis[i]; } cout<<ans<<endl; } void solve(){ memset(cnt,0,sizeof(cnt)); spfa(); put(); } } int main(){ //freopen("a.in","r",stdin); //freopen("a.out","w",stdout); using namespace zhangenming; init(); solve(); return 0; }