• [spfa][差分约束] Bzoj 2330 糖果


    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
    

    Sample Output

    11

    Hint

    对于30%的数据,保证 N<=100
    对于100%的数据,保证 N<=100000
    对于所有的数据,保证 K<=100000,1<=X<=5,1<=A, B<=N

    题解

    • 这很显然就是差分约束系统,然后跑最长路就好了

    代码

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <queue> 
     5 #define ll long long
     6 using namespace std;
     7 const int N=300010;
     8 int n,k,cnt,head[N],dis[N],tot[N];
     9 ll ans;
    10 bool vis[N];
    11 queue<int>Q;
    12 struct edge {int to,from,v;}e[N];
    13 void insert(int x,int y,int v) { e[++cnt].to=y,e[cnt].from=head[x],e[cnt].v=v,head[x]=cnt; }
    14 int read()
    15 {
    16     char ch=getchar(); int x=0;
    17     while (ch<'0'||ch>'9') ch=getchar();
    18     while (ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar(); 
    19     return x;
    20 }
    21 int main()
    22 {
    23     n=read(),k=read();    
    24     for (int i=1,x,a,b;i<=k;i++)
    25     {
    26         x=read(),a=read(),b=read();
    27         if (x==1) insert(a,b,0),insert(b,a,0);
    28         if (x==2) 
    29         {
    30             if (a==b) { printf("-1"); return 0; }
    31             insert(a,b,1);
    32         }
    33         if (x==3) insert(b,a,0);
    34         if (x==4)
    35         {
    36             if (a==b) { printf("-1"); return 0; }
    37             insert(b,a,1);
    38         }
    39         if (x==5) insert(a,b,0);
    40     }
    41     for (int i=n;i>=1;i--) insert(0,i,1);
    42     vis[0]=1,Q.push(0);
    43     while (!Q.empty())
    44     {
    45         int u=Q.front(); Q.pop(),vis[u]=0;
    46         if (tot[u]==n-1) { printf("-1"); return 0; }
    47         tot[u]++;
    48         for (int i=head[u];i;i=e[i].from)
    49             if (dis[e[i].to]<dis[u]+e[i].v)
    50             {
    51                 dis[e[i].to]=dis[u]+e[i].v;
    52                 if (!vis[e[i].to]) Q.push(e[i].to),vis[e[i].to]=1;
    53             }
    54     }
    55     for (int i=1;i<=n;i++) ans+=dis[i];
    56     printf("%lld",ans);
    57 }
  • 相关阅读:
    微信公众平台开发心得笔记
    MFC中 在线程里获取主对话框上编辑框中的内容
    MFC中 使用Tab Control 控件在对话框中添加属性页
    MFC中 将std::string转换为LPCTSTR的方法
    MFC中 给按钮添加图片的方法
    MFC中 使用多线程实现语音播放功能
    MFC中 Group Box 控件会覆盖掉部分其他控件
    MFC中 CSting与std::string互相转换
    MFC中 给对话框添加背景图片
    MFC中 通过对子对话框的操作来更新主对话框
  • 原文地址:https://www.cnblogs.com/Comfortable/p/11139197.html
Copyright © 2020-2023  润新知