拓扑排序
类似于a<b,c<b,d<c,可以找到一个关系是a<d<c<b。意思就是有好几件事ABCD,B要在A后面做,C要在B后面做等等,然后对每个事件的先后顺序进行排序。
做法就是每次删除一个入度为零的点,而这个点指向的点的入度就减一,循环下去直到所有结点被找出来。如果排序失败,表示有环。
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<cmath>
#include<cstring>
#define MAXN 517
using namespace std;
int G[MAXN][MAXN];
int ds[MAXN];
int ans[MAXN];
int n, m, x, y;
int i, j;
void tp();
void init();
int main()
{
while (cin >> n >> m)
{
init();
for (i = 0;i < m;i++)
{
cin >> x >> y;
G[x][y] = 1;
}
tp();
for (i = 1;i < n;i++)
{
cout << ans[i] << ' ';
}
cout << ans[n] << endl;
}
}
void tp()
{
for (i = 1; i <= n; i++)
{
for (j = 1; j <= n; j++)
{
if (G[i][j])
{
ds[j]++; //记录每个结点的入度
}
}
}
for (int i = 1;i <= n;i++)
{
int k = 1;
while (ds[k] != 0) //找到入度为零的点
{
k++;
}
ans[i] = k; //该点进排序列
ds[k] = -1;
for (int j = 1;j <= n;j++) //该点指向的点的入度都减一
{
if (G[k][j])
{
ds[j]--;
}
}
}
}
void init()
{
memset(ds, 0, sizeof(ds));
memset(ans, 0, sizeof(ans));
memset(G, 0, sizeof(G));
}
来源:https://blog.csdn.net/qq_44146257/article/details/100804835