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

    DZY Loves Topological Sorting

    Time Limit: 1 Sec  Memory Limit: 256 MB

    题目连接

    http://acm.hdu.edu.cn/showproblem.php?pid=5195

    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 v, u comes 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. (TestCase≤5)
    The first line, three integers n,m,k(1≤n,m≤105,0≤k≤m).
    Each of the next m lines has two integers: u,v(u≠v,1≤u,v≤n), representing a direct edge(u→v).

    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

    题意

    一张有向图的拓扑序列是图中点的一个排列,满足对于图中的每条有向边(u→v) 从 u 到 v,都满足u在排列中出现在v之前。
    现在,DZY有一张有向无环图(DAG)。你要在最多删去k条边之后,求出字典序最大的拓扑序列。

    题解:

    因为我们要求最后的拓扑序列字典序最大,所以一定要贪心地将标号越大的点越早入队。我们定义点i的入度为di。假设当前还能删去k条边,那么我们一定会把当前还没入队的di≤k的最大的i找出来,把它的di条入边都删掉,然后加入拓扑序列。可以证明,这一定是最优的。
    具体实现可以用线段树维护每个位置的di,在线段树上二分可以找到当前还没入队的di≤k的最大的i。于是时间复杂度就是O((n+m)logn).

    代码:

    //qscqesze
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <vector>
    #include <sstream>
    #include <queue>
    #include <typeinfo>
    #include <fstream>
    #include <map>
    #include <stack>
    typedef long long ll;
    using namespace std;
    //freopen("D.in","r",stdin);
    //freopen("D.out","w",stdout);
    #define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
    #define maxn 200001
    #define mod 10007
    #define eps 1e-9
    int Num;
    char CH[20];
    //const int inf=0x7fffffff;   //нчоч╢С
    const int inf=0x3f3f3f3f;
    /*
    
    inline void P(int x)
    {
        Num=0;if(!x){putchar('0');puts("");return;}
        while(x>0)CH[++Num]=x%10,x/=10;
        while(Num)putchar(CH[Num--]+48);
        puts("");
    }
    */
    //**************************************************************************************
    inline ll read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    inline void P(int x)
    {
        Num=0;if(!x){putchar('0');puts("");return;}
        while(x>0)CH[++Num]=x%10,x/=10;
        while(Num)putchar(CH[Num--]+48);
        puts("");
    }
    int du[100005];
    int vis[100005];
    vector<int> lin[100005];
    int n,m,k;
    int t[500005];
    int arr[100005];
    void build(int i,int l,int r)
    {
        if (l==r)
        {
            t[i]=du[l];
            arr[l]=i;
            return;
        }
        int mid=(l+r)/2;
        build(i*2,l,mid);
        build(i*2+1,mid+1,r);
        t[i]=min(t[i*2],t[i*2+1]);
        return;
    }
    int query(int i,int l,int r,int k)
    {
        if (l==r)
            return l;
        int mid=(l+r)/2;
        if (t[i*2+1]<=k) return query(i*2+1,mid+1,r,k);
        else return query(i*2,l,mid,k);
    }
    void insert(int i,int l,int r,int wei,int cc)
    {
        if (l==r)
        {
            t[i]+=cc;
            return;
        }
        int mid=(l+r)/2;
        if (wei<=mid) insert(i*2,l,mid,wei,cc);
        else insert(i*2+1,mid+1,r,wei,cc);
        t[i]=min(t[i*2],t[i*2+1]);
        return;
    }
    int main()
    {
        while (cin>>n>>m>>k)
        {
            memset(vis,0,sizeof(vis));
            memset(du,0,sizeof(du));
            for (int i=1;i<=n;i++)
                lin[i].clear();
            int i,j;
            for (int tt=1;tt<=m;tt++)
            {
                scanf("%d%d",&i,&j);
                lin[i].push_back(j);
                du[j]++;
            }
            int nn=0;
            int flag=0;
            build(1,1,n);
            for (int i=1;i<=n;i++)
            {
                int c=query(1,1,n,k);
                if (flag) printf(" ");
                printf("%d",c);
                flag=1;
                k-=du[c];
                insert(1,1,n,c,9999999);
                for (int kk=0;kk<lin[c].size();kk++)
                {
                    int j=lin[c][kk];
                    insert(1,1,n,j,-1);
                    du[j]--;
                }
    
            }
            printf("
    ");
        }
    }
  • 相关阅读:
    在Fedora 8 下安装Fcitx输入法
    iisweb服务器完美解决方案
    利用httpget实现计划任务访问某一指定页面
    如何升级到SQL Server 2005
    排除“计算机默认 权限设置未将 COM 服务器应用程序”的错误
    Windows 2003 服务器安全设置
    Linux Fedora8 下安装 IE6
    配置 SQL Server 以便使用 2 GB 以上的物理内存(包括SQL Server 2005)
    Entity Framework初探
    async、await在ASP.NET[ MVC]中之线程死锁的故事
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4446035.html
Copyright © 2011-2022 走看看