题目:https://vjudge.net/problem/UVA-10305
基础知识:
拓扑排序:把一个图中的所有结点排序,对于每一条有向边(u,v),使u都在v的前面
如图中存在有向环,则不存在拓扑排序,反之存在。
不包含有向环的有向图称为有向无环图DAG(Directed Acyclic Graph)
解题思路:
本题是一道拓扑排序模版题,注意,在用dfs完成拓扑排序时,在访问完一个结点后要把它加到当前拓扑排序数组的尾部
c[u]=0;表示从未访问过(未调用dfs(u))
c[u]=1;表示已经访问过,并且递归访问过它的所有子孙(dfs(u)已返回结果)
c[u]=-1;表示正在访问,(dfs(u)正在栈帧中,但未返回)
ac代码:
#include <iostream>
#include <cmath>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#define maxn 110
#define inf 1e+9+10
using namespace std;
typedef long long ll;
int n,m,t,c[maxn],topo[maxn],G[maxn][maxn];
bool dfs(int u)
{
c[u]=-1;//正在访问
for(int v=1;v<=n;v++)
if(G[u][v])
{
if(c[v]<0)//存在有向环
return false;
else if(!c[v]&&!dfs(v)) return false;//v未访问且以其继续bfs会false
}
c[u]=1;//已访问完毕
topo[--t]=u;
return true;
}
bool toposort()
{
t=n;
memset(c,0,sizeof(c));
for(int u=1;u<=n;u++)
if(!c[u])//未访问过
if(!dfs(u)) return false;//拓扑排序失败
return true;
}
int main()
{
//freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);
//ios::sync_with_stdio(false);
int a,b,i;
while(scanf("%d %d",&n,&m)==2)
{
if(m==0&&n==0) break;
memset(G,0, sizeof(G));
for(i=0;i<m;i++)
{
scanf("%d %d",&a,&b);
G[a][b]=1;
}
toposort();
for(i=0;i<n;i++)
{
if(i)
printf(" ");
printf("%d",topo[i]);
}
printf("\n");
}
return 0;
}