拓扑排序 反向建图

https://ac.nowcoder.com/acm/problem/20115

在这里插入图片描述
思路
反向建图,然后让入度为0的进入优先队列,就是按照层次来一个个比较

#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
int ans[100010],n,m;
int head[100010],nex[100010],ver[100010],tot,d[100010];
void init()
{
    tot=0;
    memset(head,0,sizeof(head));
    memset(d,0,sizeof(d));
}
void add(int u,int v)
{
	tot++;
	nex[tot]=head[u];
	ver[tot]=v;
	head[u]=tot;
}
void topsort()
{
    priority_queue<int>q;              //因为是反向,输出也反向,所以最大的放在最后,最小的则最前
    int cnt=0;
    for(int i=1;i<=n;i++)if(!d[i])q.push(i);
    while(!q.empty())
    {
        int u=q.top();q.pop();
        ans[cnt++]=u;
        for(int i=head[u];i;i=nex[i])
        {
            int v=ver[i];
            if(--d[v]==0)q.push(v);
        }
    }
    if(cnt!=n)puts("Impossible!");       //出现环或者不合题意
    else
    {
		for(int i=cnt-1;i>=0;i--)         //反向输出
        	printf("%d%c",ans[i],i==0?'\n':' ');
	}
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        init();
        scanf("%d %d",&n,&m);
        for(int i=0;i<m;i++)
        {
            int u,v;                 //因为最小的要最先做,所以反向建图,这样才能看出每道菜的终点哪个最小
            scanf("%d%d",&u,&v);
            add(v,u);
            d[u]++;
        }
		topsort();
    }
}
发布了88 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44879687/article/details/102880981