一、定义:
对一个有向无环图(Directed Acyclic Graph简称DAG) G进行拓扑排序
是将G中所有顶点排成一个线性序列
使得图中任意一对顶点u和v
若边(u,v)∈E(G)
则u在线性序列中出现在v之前

注意:
有时候,这里的排序不是唯一的
二、算法 O(V+E)
有两种:入度表、dfs
(一)、入度表 O(V+E):
找出图中0入度的点
依次在图中删除这些点
于是再找删掉点之后的0入度的点
然后再删除...再找点
入度为0的点 用 队列
图 用 邻接表
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 10005;
int n,m,cnt;//cnt存储ans数组的下标
bool a[maxn][maxn];//邻接矩阵
int edge[maxn],ans[maxn];//edge[i]第i个点的入度,ans答案队列
queue<int> q;
void topo_sort()
{
for(int i = 1;i <= n;i++)
if(!edge[i])
q.push(i);//将所有入度为0的点加入队列中
while(!q.empty())
{
const int u = q.front();
ans[++cnt] = u;
q.pop();
for(int i = 1;i <= n;i++)
if(a[u][i])
{
edge[i]--;
if(!edge[i])
q.push(i);
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i = 1;i <= m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
a[x][y] = 1;
edge[y]++;
}
topo_sort();
if(cnt < n)
{
printf("有环\n");
return 0;
}
for(int i = 1;i <= n;i++)
printf("%d ",ans[i]);
return 0;
}
(二)、dfs O(n2)
(又要咕咕咕了...也不知道要咕多久qwq)
(洛谷居然出了一片日报,嘎!)
(dfs只能判断有没有还环??!(hushuobadao
用一个int类型的visit数组 标记节点
其中-1表示回到自己(即 产生了环) 这届return
否则,跑一边这个图,跑完了就没有环
//拓扑排序dfs(只判断是否有环
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 10005;
int n,m;
bool a[maxn][maxn];//邻接矩阵建图
bool flag;//判断是否有环,有环就true
int vis[maxn];//标记节点,注意是int类型,因为要用到-1,1,0
void dfs(int k)
{
vis[k] = -1;//特殊标记
for(int i = 1;i <= n;i++)
{
if(vis[i] == 0 && a[k][i] == true)
{
dfs(i);
vis[i] = 1;
}
if(vis[i] == 1 && a[k][i] == true)
{
printf("有环\n");
flag = true;
return;
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i = 1;i <= m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
a[x][y] = true;
}
dfs(1);
if(!flag)
printf("无环\n");
return 0;
}
(我..算不算没gu很久wa.)
来源:https://www.cnblogs.com/darlingroot/p/10786357.html