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/+

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

  • 相关阅读:
    C# richtextbox 自动下拉到最后 方法 & RichTextBox读取txt中文后出现乱码
    SQL基础问题整理
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    Springcloud +redis集群
    详述一次大量删除导致MySQL慢查的分析
    2019年开源数据库报告发布:MySQL仍卫冕!
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/12255326.html
Copyright © 2011-2022 走看看