GYM100792K King‘s rout

来源:互联网 发布:阿里巴巴的域名是什么 编辑:程序博客网 时间:2024/05/27 06:56

题意:

  有n个人,让你给排个序,其中有一些规则,首先要满足对于序对<a,b>,a要在b的前面输出,对于没有标定次序的序号,要满足,越小的序号,越先输出越好;

  思路:反向拓扑排序+优先队列

            对于给定的序列<a,b>,让a的度数加一,这样一定可以保证满足上面两个规则,最后输出的时候倒序输出,因为最后应该数,肯定是按照这样的度数为0 的点。

代码如下:

#include <cstdio>#include <algorithm>#include <queue>#include <vector>#include <cstring>using namespace  std;const int maxn=200000+20;vector<int> G[maxn];int ans[maxn];int indegree[maxn];priority_queue<int> p;int vis[maxn];void bfs(int x){    for(int i=0; i<G[x].size(); i++)    {        indegree[G[x][i]]--;        if(!indegree[G[x][i]])        {            if(vis[G[x][i]]) continue;            p.push(G[x][i]);            vis[G[x][i]]=1;        }    }}int main(){    int n,m;    while(!p.empty()) p.pop();    memset(indegree,0,sizeof(indegree));    memset(ans,0,sizeof(ans));    memset(vis,0,sizeof(vis));    int cnt=0;    scanf("%d%d",&n,&m);    for(int i=0; i<=n; i++)        G[i].clear();    for(int i=0; i<m; i++)    {        int x,y;        scanf("%d%d",&x,&y);        indegree[x]++;        G[y].push_back(x);    }    for(int i=1; i<=n; i++)    {        if(indegree[i]==0)        {            p.push(i);            vis[i]=1;        }    }    while(!p.empty())    {        int x=p.top();        p.pop();        ans[cnt++]=x;        bfs(x);    }    for(int i=cnt-1; i>=0; i--)    {        if(i==cnt-1) printf("%d",ans[i]);        else printf(" %d",ans[i]);    }    printf("\n");    return 0;}


         

原创粉丝点击