定义:在一个有向无环图中,规定<u,v>表示一条由u指向v的有向边,要求对所有节点进行排序,使得每一条有向边<u,v>中u排在v的前面
用途:
- 寻找一个,或满足特定要求的拓扑序列
- 判断有向图是否有环
- 做分层
实现方法:
- 从有向图中选择一个入度为0的点并输出
- 从图中删除该顶点以及以该顶点为起点的所有边
- 重复上述两步,直到所有顶点输出,或当前图中不存在入度为0的点(有环)
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=100;
const int maxm=10009;
struct node{
int id;
int next;
}side[maxm];
int head[maxn],cnt,ans[maxn],in[maxn],rank[maxn];//in[i]记录每个点的入度,rank[i]表示i在第几层
void add(int x,int y)
{
side[cnt].id=y;
side[cnt].next=head[x];
head[x]=cnt++;
}
void init()
{
memset(head,-1,sizeof(head));
cnt=0;
}
int main()
{
int n,m,x,y;
scanf("%d%d",&n,&m);
init();
memset(in,0,sizeof(in));
memset(rank,0,sizeof(rank));
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
in[y]++;
}
priority_queue<int ,vector<int>,greater<int> > q;
for(int i=1;i<=n;i++)
if(in[i]==0)
q.push(i);
int k=0;
while(q.size())
{
int tmp=q.top();
q.pop();
ans[k++]=tmp;
for(int i=head[tmp];i!=-1;i=side[i].next)
{
int y=side[i].id;
in[y]--;
rank[y]=max(rank[tmp]+1,rank[y]);
if(in[y]<=0)
q.push(y);
}
}
for(int i=0;i<k;i++)
printf("%d ",ans[i]);
printf("\n");
for(int i=1;i<=n;i++)
printf("%d ",rank[i]);
return 0;
}