拓扑排序 tzoj6082

 

反向拓扑:(正向行不通,这题要求序号小的尽量排前面,而不是要求字典序)

比如输入:

1

3 1

3 1

则仅有3指向1,正向拓扑结果是2,3,1;但并不是正确结果

题目要求序号小尽量排前面,可以是3,1,2;这样1就往前排了

所以用反向拓扑,把图画反,用优先队列(大到小)进行拓扑(保证小的在后),最后倒序输出即可

 

#include<bits/stdc++.h>
using namespace std;
int n,m;
vector<int>edge[30005];
int in[30005];
map<int,int>mp;
void topu()
{
    priority_queue<int>q;
    for(int i=1;i<=n;i++)  //n  节点的总数
        if(in[i]==0) q.push(i);  //将入度为0的点入队列
    vector<int>ans;   //ans 为拓扑序列
    while(!q.empty())
    {
        int p=q.top(); q.pop(); // 选一个入度为0的点,出队列
        ans.push_back(p);
        for(int i=0;i<edge[p].size();i++)
        {
            int y=edge[p][i];
            in[y]--;
            if(in[y]==0)
                q.push(y);
        }
    }
    printf( "%d",ans[ans.size()-1] );
    for(int i=ans.size()-2;i>=0;i--)
        printf( " %d",ans[i] );
    printf("\n");
}
int main()
{
    int i,t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        mp.clear();
        memset(in,0,sizeof(in));
        for(i=1;i<=n;i++)edge[i].clear();
        while(m--){
            int x,y;
            scanf("%d%d",&x,&y);
            in[x]++;
            edge[y].push_back(x);
        }
        topu();
    }
    return 0;
}
View Code

 

posted @ 2020-05-15 22:59  -第4题-  阅读(170)  评论(0编辑  收藏  举报