• BZOJ-2330-[SCOI2011]糖果(差分约束)


    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

     

    题解

    一道裸的差分约束(还不懂差分约束的童鞋可以上百度了解一下)

    加完边后,我们设一个虚点把1~n都加一条1的边,跑一下最长路就可以了

    不过这道题有一些坑:

    1.虚点加边的时候要倒着加,不然会T

    2.最后的答案会爆int,要开long long

     1 #include<bits/stdc++.h>
     2 #define N 100005 
     3 #define K 100005
     4 #define ll long long
     5 using namespace std;
     6 int n,k,x,a,b,tot;
     7 ll ans;
     8 int head[N],visit[N];
     9 ll dis[N];
    10 bool flag[N];
    11 int q[10*N];
    12 struct node{
    13     int next,to,dis;
    14 }e[3*K];
    15 void add(int x,int y,int z){
    16     e[++tot].next=head[x];
    17     head[x]=tot;
    18     e[tot].to=y;
    19     e[tot].dis=z;
    20 }
    21 bool spfa(){
    22     for (int i=1;i<=n;i++) flag[i]=false,visit[i]=0;
    23     int t=1,w=1;
    24     q[1]=0; flag[0]=true; visit[0]=1;
    25     while (t<=w){
    26         int k=q[t];
    27         for (int i=head[k];i;i=e[i].next){
    28             int v=e[i].to;
    29             if (dis[v]<dis[k]+e[i].dis){
    30                 dis[v]=dis[k]+e[i].dis;
    31                 if (!flag[v]){
    32                     visit[v]++;
    33                     if (visit[v]>n) return false;
    34                     flag[v]=true;
    35                     q[++w]=v;
    36                     if (dis[q[w]]<dis[q[t+1]]) swap(q[w],q[t+1]);
    37                 }
    38             }
    39         }
    40         flag[k]=false;
    41         t++;
    42     }
    43     return true;
    44 }
    45 int main(){
    46     scanf("%d%d",&n,&k);
    47     for (int i=1;i<=k;i++){
    48         scanf("%d%d%d",&x,&a,&b);
    49         if (!(x&1)&&a==b){
    50             puts("-1");
    51             return 0;
    52         }
    53         switch (x){
    54             case 1:add(a,b,0);add(b,a,0);break;
    55             case 2:add(a,b,1);break;
    56             case 3:add(b,a,0);break;
    57             case 4:add(b,a,1);break;
    58             case 5:add(a,b,0);break;
    59         }
    60     }
    61     for (int i=n;i>=1;i--) add(0,i,1);
    62     if (!spfa()){
    63         puts("-1");
    64         return 0;
    65     }
    66     for (int i=1;i<=n;i++) ans+=dis[i];
    67     printf("%lld
    ",ans);
    68     return 0;
    69 } 
    View Code
  • 相关阅读:
    怎么让Windows10取消开机登录密码自动登录
    window查看无线网卡bssid以及相关信息命令
    kali-cdlinux-wifi-pj-nanke-心得
    html里文本保留换行格式
    window实用快捷键-ctrl篇
    mybatis 结果映射 collection oftype为string,integer等类型
    Redis集群下只有db0,不支持多db
    软件开发过程中所使用的生命周期模型比较
    简单Dos命令
    简单理解Mysql json数据类型
  • 原文地址:https://www.cnblogs.com/zhuchenrui/p/7802488.html
Copyright © 2020-2023  润新知