zoukankan      html  css  js  c++  java
  • hdu 5195 DZY Loves Topological Sorting (拓扑排序+线段树)

    DZY Loves Topological Sorting

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
    Total Submission(s): 1250    Accepted Submission(s): 403


    Problem Description
    A topological sort or topological ordering of a directed graph is a linear ordering of its vertices such that for every directed edge (uv) from vertex u to vertex vucomes before v in the ordering.
    Now, DZY has a directed acyclic graph(DAG). You should find the lexicographically largest topological ordering after erasing at most k edges from the graph.
     
    Input
    The input consists several test cases. (TestCase5)
    The first line, three integers n,m,k(1n,m105,0km).
    Each of the next m lines has two integers: u,v(uv,1u,vn), representing a direct edge(uv).
     
    Output
    For each test case, output the lexicographically largest topological ordering.
     
    Sample Input
    5 5 2 1 2 4 5 2 4 3 4 2 3 3 2 0 1 2 1 3
     
    Sample Output
    5 3 1 2 4 1 3 2
    Hint
    Case 1. Erase the edge (2->3),(4->5). And the lexicographically largest topological ordering is (5,3,1,2,4).
     
    思路:
    用线段树维护区间最小值。
     
    ps.之前没在查询操作加个pushup,一直跑不出答案,因为在查询过程中,sum的值是更新了的,所以要pushup下
    实现代码:
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define mid int m = (l + r) >> 1
    const int M = 2e5+10;
    const int inf = 0x3f3f3f3f;
    int n,m,cnt,key;
    vector<int>g[M];
    int sum[M<<2],du[M];
    void pushup(int rt){
        sum[rt] = min(sum[rt<<1],sum[rt<<1|1]);
    }
    
    void build(int l,int r,int rt){
        if(l == r){
            sum[rt] = du[l];
            return;
        }
        mid;
        build(lson);
        build(rson);
        pushup(rt);
    }
    
    void update(int p,int l,int r,int rt){
        if(l == r){
            sum[rt]--;
            return ;
        }
        mid;
        if(p <= m) update(p,lson);
        else  update(p,rson);
        pushup(rt);
    }
    
    void query(int l,int r,int rt){
        if(l == r){
            cnt -= sum[rt];
            key = l;
            sum[rt] = inf;
            return ;
        }
        mid;
        if(sum[rt<<1|1] <= cnt) query(rson);
        else query(lson);
        pushup(rt);
    }
    
    int main(){
        int u,v;
        while(cin>>n>>m>>cnt){
            for(int i = 1;i <= m;i ++){
                cin>>u>>v;
                g[u].push_back(v);
                du[v]++;  //入度
            }
            build(1,n,1);
            for(int i = 1;i <= n;i ++){
                query(1,n,1);
                if(i==1) cout<<key;
                else cout<<" "<<key;
                for(int j = 0;j < g[key].size();j++){
                    int x = g[key][j];
                    update(x,1,n,1);
                }
            }
            cout<<endl;
            memset(du,0,sizeof(du));
        }
        return 0;
    }
  • 相关阅读:
    HDU 4291 A Short problem 第37届ACM/ICPC 成都赛区网络赛1004题 (找规律,取模求循环节)
    POJ 1276 Cash Machine(多重背包)
    HDU 4296 Buildings 第37届ACM/ICPC 成都赛区网络赛1009题 (贪心)
    POJ 2392 Space Elevator (多重背包)
    Mysql配置SSL
    error C2471: cannot update program database vc90.pdb
    Android 总结 转载
    MAX SDK的INode的变换矩阵,以及Object的一些常识
    C++游戏开发需要阅读的书籍
    游戏程序员养成计划
  • 原文地址:https://www.cnblogs.com/kls123/p/8834781.html
Copyright © 2011-2022 走看看