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

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

  • 相关阅读:
    HDU 1058 Humble Numbers
    HDU 1160 FatMouse's Speed
    HDU 1087 Super Jumping! Jumping! Jumping!
    HDU 1003 Max Sum
    HDU 1297 Children’s Queue
    UVA1584环状序列 Circular Sequence
    UVA442 矩阵链乘 Matrix Chain Multiplication
    DjangoModels修改后出现You are trying to add a non-nullable field 'download' to book without a default; we can't do that (the database needs something to populate existing rows). Please select a fix:
    opencv做的简单播放器
    c++文件流输入输出
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/12255326.html
Copyright © 2011-2022 走看看