zoukankan      html  css  js  c++  java
  • 题解——洛谷P3275 [SCOI2011]糖果

    一道条件非常多的差分约束

    把( a < b )转化为( a-b le -1)就可做了

    ( a>b )的情况同理

    若有负环则无解输出-1

    注意本题中要求每个人都有糖果

    所以假设一个源点( d_{0} ),使( d_{i}-d_{0} ge 1  , (1 le i le n) )

    另外,本题要求得是最小值

    ( x_{i}-x_{j} le a_{k} )的形式求出的是最大值

    要转化成 ( x_{j}-x_{i} ge a_{k} )的形式求解最小值

    每个人的最小值即为( dis_{i} ),所以求和

    因为和是负数,所以输出-ans

    ans会爆int

    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #include <cstring>
    using namespace std;
    const int MAXN = 100010;
    const int MAXM = 500000;
    int cnt=0,u[MAXM],v[MAXM],w[MAXM],first[MAXN],next[MAXM];
    bool vis[MAXN];
    int inq[MAXN],dis[MAXN],f[MAXN];
    int n,k;
    void addedge(int ux,int vx,int wx){
        ++cnt;
        u[cnt]=ux;
        v[cnt]=vx;
        w[cnt]=wx;
        next[cnt]=first[ux];
        first[ux]=cnt;
    }
    bool spfa(int s){
        queue<int> q;
        for(int i=0;i<=n;i++)
                dis[i]=0x3f3f3f3f;
        q.push(s);
        dis[s]=0;
        inq[s]=1;
        vis[s]=1;
        f[s]=1;
        while(!q.empty()){
            int u=q.front();
            q.pop();
            vis[u]=0;
            f[u]=1;
            for(int i=first[u];i;i=next[i]){
                if(w[i]+dis[u]<dis[v[i]]){
                    dis[v[i]]=w[i]+dis[u];
                    if(!vis[v[i]]){
                        vis[v[i]]=1;
                        inq[v[i]]++;
                        q.push(v[i]);
                        if(inq[v[i]]>=n)
                            return false;
                    }
                }
            }
        }
        return true;
    }
    int main(){
        scanf("%d %d",&n,&k);
        int x,a,b;
        for(int i=1;i<=k;i++){
            scanf("%d",&x);
            if(x==1){
                scanf("%d %d",&a,&b);
                addedge(a,b,0);
                addedge(b,a,0);
            }
            else if(x==2){
                scanf("%d %d",&a,&b);
                addedge(a,b,-1);
                if(a==b){
                    printf("-1");
                    return 0;
                }
            }
            else if(x==3){
                scanf("%d %d",&a,&b);
                addedge(b,a,0);
            }
            else if(x==4){
                scanf("%d %d",&a,&b);
                addedge(b,a,-1);
                if(a==b){
                printf("-1");
                return 0;
                }
            }
            else{
                scanf("%d %d",&a,&b);
                addedge(a,b,0);
            }
        }
        for(int i=n;i>=1;i--)
            addedge(0,i,-1);
        if(!spfa(0)){
            printf("-1");
            return 0;
        }
        long long ans=0;
        for(int i=1;i<=n;i++)
            ans+=-dis[i];
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    spark的做算子统计的Java代码(在Linux系统集群式运行)
    http协议面试题
    vue响应式原理
    vue-cli3搭建vue项目
    vscode中自定义代码片段
    vue中常用的全局配置
    tomcat安装配置
    Git相关
    nginx配置文件详解
    nginx源码安装
  • 原文地址:https://www.cnblogs.com/dreagonm/p/9433496.html
Copyright © 2011-2022 走看看