拓扑排序

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=100010;
struct edge{ int t; edge * nxt; edge(int to, edge * next){ t=to, nxt=next; } };
edge * h[maxn];
void add(int u, int v) { h[u]=new edge(v, h[u]); }
int n, m, indegree[maxn], dp[maxn], seq[maxn<<1];			//seq存储其中一种拓扑序列 
 
int topo()
{
    queue<int>q;
    for(int i=1; i<=n; i++)	if(indegree[i]==0)	q.push(i), dp[i]=1;
	int k=0;												//seq中存储的下标 
	bool _unique=true;										//标记是否有唯一的排序 
    while(!q.empty())
    {
        if(q.size()>1)	_unique=false;						//有多个入度为0的点,拓扑排序不唯一 
        int u=q.front();
        q.pop();
        seq[++k]=u;
        if(k>n)	return -1;									//存在有向环,不能进行拓扑排序
        for(edge *p=h[u]; p; p=p->nxt)
        {
            indegree[p->t]--;
            dp[p->t]=max(dp[p->t], dp[u]+1);
            if(indegree[p->t]==0)	q.push(p->t);
        }
    }
    return _unique;											//1表示排序唯一,0表示有多种排序,存在seq中 
}

int main()
{
	scanf("%d%d", &n, &m);
	for(int i=1, x, y; i<=m; i++) 	scanf("%d%d", &x, &y), add(x, y), indegree[y]++;
	if(topo()>=0)
		for(int i=1; i<=n; i++)		printf("%d\n", dp[i]);
	return 0;
}
posted @ 2019-03-27 16:48  LFYZOI题解  阅读(138)  评论(0编辑  收藏  举报