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
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;
}