hdu 5195 DZY Loves Topological Sorting【拓扑排序+优先队列+邻接表】

来源:互联网 发布:fastcam套料软件下载 编辑:程序博客网 时间:2024/05/21 19:39

DZY Loves Topological Sorting

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


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 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 mostk 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 21 24 52 43 42 33 2 01 21 3
 


Sample Output
5 3 1 2 41 3 2
Hint
Case 1.Erase the edge (2->3),(4->5).And the lexicographically largest topological ordering is (5,3,1,2,4).


题目大意:

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

题目保证了图是合法的拓扑图、这里我们就不用多担心了。这里说要删除k条边,然后求出字典序最大的拓扑排序,看到这里,我们马上就应该有一种贪心的思想:去边的时候,找度小于等于k的点,使这个点的编号尽量大,然后去度、这里求的是字典序最大的拓扑序列,我们可以应用优先队列来搞定

因为图比较大,所以这里用vector来搞定图的问题:

#include<stdio.h>#include<string.h>#include<queue>#include<algorithm>#include<vector>using namespace std;int now,head[200010],nex[200010],p[200010];int vis[200010];int degree[200010];vector<int>map[200010];int ans[200010];/*void add(int x,int y){    nex[++now]=head[x];    head[x]=now;    p[now]=y;}*/int main(){    int n,m,k;    while(~scanf("%d%d%d",&n,&m,&k))    {        for(int i=1;i<=n;i++)        {            map[i].clear();        }        memset(vis,0,sizeof(vis));        memset(degree,0,sizeof(degree));        memset(head,0,sizeof(head));        now=0;        while(m--)        {            int x,y;            scanf("%d%d",&x,&y);            map[x].push_back(y);            //add(x,y);            degree[y]++;        }        priority_queue<int>s;        for(int i=1;i<=n;i++)        {            if(degree[i]<=k)            s.push(i);        }        int cont=0;        while(!s.empty())        {            int u=s.top();            s.pop();            if(vis[u]||degree[u]>k)continue;            vis[u]=1;            k-=degree[u];            ans[++cont]=u;            for(int j=0;j<map[u].size();j++)            {                int v=map[u][j];                degree[v]--;                if(degree[v]<=k&&vis[v]==0)                s.push(v);            }            /*            for(int i=head[u];i;i=nex[i])            {                int v=p[i];                degree[v]--;                if(degree[v]<=k&&vis[v]==0)                s.push(v);            }*/        }        for(int i=1;i<cont;i++)        {            printf("%d ",ans[i]);        }        printf("%d\n",ans[cont]);    }}










0 0