zoukankan      html  css  js  c++  java
  • 洛谷3275 & BZOJ2330:[SCOI2011]糖果——题解

    https://www.luogu.com.cn/problem/P3275

    https://www.lydsy.com/JudgeOnline/problem.php?id=2330

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

    当差分约束练习……个鬼啊怎么还要缩点的啊。

    先按照正常的差分约束建图,别忘了为了保证每个孩子都要有糖于是多来一个点,所有的点连向它边权为-1……不对啊这图怎么建完了没法构造能够通向所有点的起点,以及边要么是0要么是-1怎么做啊……

    把所有边反过来的同时边权取相反数,变成求最长路(然后就可以看到题解区一堆牛鬼蛇神般玄学求最长路的方法……比较无语)

    首先把0边单独提出来缩一波点,然后再把所有的边提出来拓扑排序一下的同时更新dis,如果搜完了发现不是DAG答案就是-1,否则答案就是dis*缩的点数。

    别忘了读入的时候也要特判无解的情况。

    #include<cmath>
    #include<stack>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N=1e5+5;
    const int M=5e5+5;
    const int INF=1e9;
    inline int read(){
        int X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    struct node{
        int u,v,w,nxt;
    }e[2][M];
    int cnt,h[2][N],indeg[N];
    inline void add(int u,int v,int w,int k){
        e[k][++cnt].u=u;e[k][cnt].v=v;e[k][cnt].w=w;
        e[k][cnt].nxt=h[k][u];h[k][u]=cnt;
        if(k)indeg[v]++;
    }
    int dfn[N],low[N],to[N],sum[N],t,l;
    stack<int>q;
    bool inq[N],vis[N];
    void tarjan(int u){
        int v;
        dfn[u]=low[u]=++t;
        q.push(u);inq[u]=1;
        for(int i=h[0][u];i;i=e[0][i].nxt){
            v=e[0][i].v;
            if(e[0][i].w)continue;
            if(!dfn[v]){
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }else if(inq[v]){
                low[u]=min(low[u],dfn[v]);
            }
        }
        if(dfn[u]==low[u]){
            l++;
            do{
                v=q.top();
                q.pop();
                inq[v]=0;
                to[v]=l;
                sum[l]++;
            }while(v!=u);
        }
    }
    int n,k;
    ll ans,dis[N];
    queue<int>p;
    bool topu(){
        int tot=0;
        for(int i=1;i<=l;i++){
            if(!indeg[i])p.push(i);
        }
        while(!p.empty()){
            int u=p.front();p.pop();++tot;
            ans+=dis[u]*sum[u];
            for(int i=h[1][u];i;i=e[1][i].nxt){
                int v=e[1][i].v,w=e[1][i].w;
                indeg[v]--;
                if(!indeg[v])p.push(v);
                dis[v]=max(dis[v],dis[u]+w);
            }
        }
        return tot==l;
    }
    int main(){
        n=read(),k=read();
        for(int i=1;i<=n;i++)add(0,i,1,0);
        for(int i=1;i<=k;i++){
            int x=read(),u=read(),v=read();
            if((x==2||x==4)&&u==v){
                puts("-1");
                return 0;
            }
            if(x==1)add(u,v,0,0),add(v,u,0,0);
            if(x==2)add(u,v,1,0);
            if(x==3)add(v,u,0,0);
            if(x==4)add(v,u,1,0);
            if(x==5)add(u,v,0,0);
        }
        for(int i=0;i<=n;i++){
            if(!dfn[i])tarjan(i);
        }
        int tmp=cnt;cnt=0;
        for(int i=1;i<=tmp;i++){
            int u=e[0][i].u,v=e[0][i].v,w=e[0][i].w;
            if(to[u]==to[v]){
                if(w){
                    puts("-1");
                    return 0;
                }
            }else add(to[u],to[v],w,1);
        }
        if(!topu())puts("-1");
        else printf("%lld
    ",ans);
        return 0;
    }

    +++++++++++++++++++++++++++++++++++++++++++

     +本文作者:luyouqi233。               +

     +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    pipelinewise 学习二 创建一个简单的pipeline
    pipelinewise 学习一 docker方式安装
    Supercharging your ETL with Airflow and Singer
    ubuntu中使用 alien安装rpm包
    PipelineWise illustrates the power of Singer
    pipelinewise 基于singer 指南的的数据pipeline 工具
    关于singer elt 的几篇很不错的文章
    npkill 一个方便的npm 包清理工具
    kuma docker-compose 环境试用
    kuma 学习四 策略
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/12255326.html
Copyright © 2011-2022 走看看