BZOJ 2330 SCOI2011 糖果

2330: [SCOI2011]糖果

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 7058  Solved: 2387
[Submit][Status][Discuss]

Description

 

幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果。但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的多,于是在分配糖果的时候,lxhgww需要满足小朋友们的K个要求。幼儿园的糖果总是有限的,lxhgww想知道他至少需要准备多少个糖果,才能使得每个小朋友都能够分到糖果,并且满足小朋友们所有的要求。

 

Input

输入的第一行是两个整数NK

接下来K行,表示这些点需要满足的关系,每行3个数字,XAB

如果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

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

 

posted @ 2017-11-05 15:28  zhangenming  阅读(144)  评论(0编辑  收藏  举报