问题描述:
对输入的有向图进行拓扑排序,并输出一个拓扑有序序列;若果存在有向环则输出:Network has a cycle!
样例输入:
6 8
1 2
1 4
2 6
3 2
3 6
5 1
5 2
5 6
6 8
1 3
1 2
2 5
3 4
4 2
4 6
5 4
5 6
0 0
样例输出:
5 1 4 3 2 6
Network has a cycle!
分析:
查找Top序列思想:
(1)在AOV网络中选择一个入度为0的顶点并输出。
(2)删除该顶点,并删除该顶点出发的所有的的边。
(3)重复(1)(2),直到找不到入度为0的顶点。
在代码中用count_[]数组存每个节点的入度数。
将入度为0的节点存入“栈”中。(代码中的栈就是在count_[]数组里实现的,思想类似于并查集)。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 1010;
vector<int> G[maxn];
int count_[maxn];
char out[maxn];
int main()
{
freopen("in.txt","r",stdin);
int n,m,u,v;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==0 && m==0) break;
memset(count_,0,sizeof(count_));
for(int i=0;i<maxn;i++)
G[i].clear();
for(int i=0;i<m;i++)
{
scanf("%d%d",&u,&v);
count_[v]++;
G[u].push_back(v);
}
int ans = n;
int top = -1;
for(int i=1;i<=n;i++)
{
if(count_[i]==0)
{
count_[i]=top;
top=i;
}
}
int pos = 0;
while(top!=-1)
{
int j=top;
top=count_[top];
pos+=sprintf(out+pos,"%d ",j);
//printf("%d ",j);
ans--;
for(int i=0;i<G[j].size();i++)
{
count_[G[j][i]]--;
if(count_[G[j][i]]==0)
{
count_[G[j][i]]=top;
top=G[j][i];
}
}
}
if(ans)
printf("Network has a cycle!\n");
else
{
int len = strlen(out);
out[len-1]=0;
printf("%s\n",out);
}
}
return 0;
}