• bzoj2330: [SCOI2011]糖果 差分约束系统


    幼儿园里有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。
    题解:差分约束系统,求相当于求0到1~n的差值最小,根据差值求最长路,如果有不等式a>=b+c,那么从b连一条权值为c的边到a,然后由于每个小朋友不能没有糖果,所以a>=1,从0开始跑一边最长路,求和即可(为什么可以?可以这么看,为了满足不等式,从b到a权值最小都是c,假设有多条b到a的权值边,那么肯定要选权值最大的那条边(因为要满足所有不等式),然后其他点同理,所以就是求最长路,从0开始跑一边单源最长路即可,)值得注意的是这题卡spfa,注意加边顺序,以及入队次数,还有自环的情况

    /**************************************************************
        Problem: 2330
        User: walfy
        Language: C++
        Result: Accepted
        Time:356 ms
        Memory:8032 kb
    ****************************************************************/
     
    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    //#pragma GCC optimize("unroll-loops")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define mod (1000000007)
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pii pair<int,int>
    #define cd complex<double>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
     
    using namespace std;
     
    const double g=10.0,eps=1e-12;
    const int N=100000+10,maxn=400000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;
     
    struct edge{
        int to,Next,c;
    }e[maxn];
    int cnt,head[N];
    void init()
    {
        cnt=0;
        memset(head,-1,sizeof head);
    }
    void add(int u,int v,int c)
    {
        e[cnt].to=v;
        e[cnt].c=c;
        e[cnt].Next=head[u];
        head[u]=cnt++;
    }
    ll dis[N];
    int n,k,in[N];
    bool vis[N];
    bool spfa()
    {
        queue<int>q;
        for(int i=1;i<=n;i++)dis[i]=-1e18;
        dis[0]=0;
        memset(vis,0,sizeof vis);
        vis[0]=1;in[0]++;
        q.push(0);
        while(!q.empty())
        {
            int u=q.front();q.pop();vis[u]=0;
            for(int i=head[u];~i;i=e[i].Next)
            {
                int x=e[i].to;
    //            printf("%d %d
    ",dis[x],dis[u]+e[i].c);
                if(dis[x]<dis[u]+e[i].c)
                {
                    dis[x]=dis[u]+e[i].c;
                    if(!vis[x])
                    {
                        vis[x]=1;
                        q.push(x);
                        in[x]++;
                        if(in[x]>=n+1)return 0;
                    }
                }
            }
        }
        return 1;
    }
    int main()
    {
        scanf("%d%d",&n,&k);
        init();
        int f=1;
        while(k--)
        {
            int x,a,b;
            scanf("%d%d%d",&x,&a,&b);
            if(x==1)add(a,b,0),add(b,a,0);
            else if(x==2){if(a==b)f=0;add(a,b,1);}
            else if(x==3)add(b,a,0);
            else if(x==4){if(a==b)f=0;add(b,a,1);}
            else add(a,b,0);
        }
        for(int i=n;i>=1;i--)add(0,i,1);
    //    for(int i=0;i<=n;i++)printf("%d %lld
    ",i,dis[i]);
        if(f==0||!spfa())puts("-1");
        else
        {
            ll ans=0;
            for(int i=1;i<=n;i++)ans+=dis[i];
            printf("%lld
    ",ans);
        }
        return 0;
    }
    /********************
    5 7
    1 1 2
    2 3 2
    4 4 1
    3 4 5
    5 4 5
    2 3 5
    4 5 1
    ********************/
    
  • 相关阅读:
    什么是Portal!
    Maven 让事情变得简单
    HTTP协议详解
    函数实现不放在头文件的原因,及何时可以放头文件的情况
    Linux中的内存管理(四)Heap
    寿星万年历Lua实现
    TCP epoll触发后只accept一次带来的问题
    生产者消费者问题
    Windows SDK 实现不规则窗口
    论迭代式的产品开发方法
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/9131463.html
Copyright © 2020-2023  润新知