对输入的有向图进行拓扑排序,并输出一个拓扑有序序列;如果存在有向环,则给出提示信息。
假设输入文件中有向图的格式为:首先是定点个数n和边数m;然后是每条边,每条边的数据占一行,格式为 u v,表示从定点u 到顶点 v的一条有向边,顶点序号从1开始计起。输入文件的最后一行为0 0,表示输入数据结束。
样例输入:
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!
#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cstdio>
using namespace std;
#define MAXN 10
struct ArcNode
{
int to;
struct ArcNode *next;
};
int n, m;
ArcNode* List[MAXN];
int Count[MAXN];
char output[100];
void TopSort()
{
int i, top = -1;
ArcNode* temp;
bool bcycle = false;
int pos = 0;
for ( i = 0;i < n;i++)
{
if (Count[i] == 0)
{
Count[i] = top;
top = i;
//cout << top << endl;
}
}
for ( i = 0;i < n;i++)
{
if (top == -1)//必定连接成环!
{
bcycle = true;
break;
}
else
{
int j = top;
top = Count[top];
pos += sprintf(output + pos, "%d ", j + 1);
temp = List[j];
while (temp != NULL)
{
int k = temp->to;
if (--Count[k] == 0)
{
Count[k] = top;
top = k;
}
temp = temp->next;
}
}
}
if (bcycle)
printf("Network has a cycle!\n");
else
{
int len = strlen(output);
output[len - 1] = 0;
printf("%s\n", output);
}
}
int main()
{
int i, u, v;
while (~scanf("%d%d", &n, &m)&&n+m)
{
memset(List, 0, sizeof(List));
memset(Count, 0, sizeof(Count));
memset(output, 0, sizeof(output));
ArcNode* temp;
for ( i = 0;i < m;i++)
{
scanf("%d%d", &u, &v);
u--;
v--;
Count[v]++;
temp = new ArcNode;
temp->to = v;
temp->next = NULL;
if (List[u] = NULL)
List[u] = temp;
else
{
temp->next = List[u];
List[u] = temp;
}
}
TopSort();
for (i = 0;i < n;i++)//释放内存
{
temp = List[i];
while (temp != NULL)
{
List[i] = temp->next;
delete temp;
temp = List[i];
}
}
}
return 0;
}