zoukankan      html  css  js  c++  java
  • Gym

    题意:给定一个N点M边的有向图,叫你加最多K条边,使得最小拓扑序最大.

    思路:不是那么简单的题.  参照了别人的代码, 最后想通了.

    贪心原则: 用两个单调队列维护, 第一个序列S1单增, 表示当前入度为0的点 ; 第二个序列S2单减,表示需要加边的点.

    如果S1的最大值大于S2的最大值,则对其加边.

    (通俗的说对于当前入度为0的点,  显然就是越小的点越需要加边,  但是我先不给它加边,  而是放到一个集合S2里,   然后遇到最大的点(不能被加边的点)来给S2的点加边.  然后可以想象, 越小的点,  加边得越晚 ,这样可以保证越小的点越被"藏得深".  然后最小拓扑可以达到最大

    #include<bits/stdc++.h> 
    using namespace std;
    const int maxn=100010;
    priority_queue<int>p;
    priority_queue<int,vector<int>,greater<int> >q;
    vector<int>G[maxn];
    int cnt,ind[maxn];
    int num,used,ans[maxn],a[maxn],b[maxn];
    void del(int v){
        ans[++num]=v;
        for(int i=0;i<G[v].size();i++) if(!--ind[G[v][i]]) q.push(G[v][i]);
        if(q.empty()){
            if(!p.empty()){
                int c=p.top(); p.pop();
                G[ans[num]].push_back(c);
                a[++used]=ans[num]; b[used]=c;
                del(c);
            }
        }
    }
    int main()
    {
        int N,M,K,u,v,i,j;
        scanf("%d%d%d",&N,&M,&K);
        for(i=1;i<=M;i++){
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            ind[v]++;
        }
        for(i=1;i<=N;i++) if(!ind[i]) q.push(i);
        while(!q.empty()){
            if(K&&(q.size()>1||(!p.empty()&&q.top()<p.top()))){
                K--;
                int c=q.top(); p.push(c); q.pop();
                if(q.empty()){
                    int c=p.top(); p.pop();
                    G[ans[num]].push_back(c);
                    a[++used]=ans[num]; b[used]=c;
                    del(c);
                }    
            }
            else{
                int c=q.top(); q.pop();
                del(c);
            }
        }
        return 0; 
    }
  • 相关阅读:
    BZOJ3589: 动态树
    BZOJ3631: [JLOI2014]松鼠的新家
    BZOJ3307: 雨天的尾巴
    BZOJ1895: Pku3580 supermemo
    BZOJ3786: 星系探索
    BZOJ2819: Nim
    解题:POI 2009 Lyz
    解题:POI 2016 Nim z utrudnieniem
    解题:POI 2004 Bridge
    解题:POI 2018 Prawnicy
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9462418.html
Copyright © 2011-2022 走看看