例:对输入的有向图进行拓扑排序,并输出一个拓扑有序序列;如果存在有向环,则给出提示信息。
输入描述:
假设输入文件中有向图的格式为:首先是顶点个数n和边数m;然后是每条边,每条边的数据占一行,格式为u v,表示从顶点u到顶点v的一条有向边,顶点序号从1开始计起。输入文件最后一行为0 0,表示输入数据结束。
样例输入: 样例输出:
6 8 5 1 4 3 2 6
1 2 Network has a cycle!
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
/*
原型
int sprintf( char *buffer, const char *format, [ argument] … );
参数列表
buffer:char型指针,指向将要写入的字符串的缓冲区。
format:格式化字符串。
[argument]...:可选参数,可以是任何类型的数据。
返回值:字符串长度(strlen)
eg:sprintf(s, "%d", 123); //产生"123"
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
using namespace std;
const int MAXN = 20;
struct ArcNode//由于是用入边链表来建图的,因此每个结点有两个指针域。
{
int data;
ArcNode *pnext;
};
int coun[MAXN];//定点度为0的入栈,这里把存放每个顶点入度的数组,与存放定点入度为0的栈融合到一起
char output[100];
ArcNode* pList[MAXN];
int n, m;
void TopSort()
{
int i, top = -1;
ArcNode* temp;
bool bcycle = false;//判断是否有环
int pos = 0;//写入output数组的位置
for(i = 0; i < n; ++i)
{
if(coun[i] == 0)//链式栈
{
coun[i] = top;
top = i;
}
}
for(i = 0; i < n; ++i)
{
if(top == -1)
{
bcycle = true;
break;
}
else
{
int j = top;//位于栈顶的顶点的位置记为j,top退至次栈顶
top = coun[top];
pos += sprintf( output + pos, "%d ", j+1 );
temp = pList[j];
//遍历顶点j 的边链表,每条出边的终点的入度减1
while( temp != NULL )
{
int k = temp->data;
if(--coun[k] == 0)//终点入度减至0,则入栈
{
coun[k] = top;
top = k;
}
temp = temp->pnext;
}
}
}
if( bcycle )
cout<<"Network has a cycle!"<<endl;
else
{
int len = strlen( output );
output[len - 1] = 0;//去掉最后的空格
cout<<output<<endl;
}
}
int main()
{
int i, u, v;//循环变量、边的起点和终点
while(1)
{
cin>>n>>m;//读入顶点个数n,边数m
if(n == 0 && m == 0)
break;
memset(pList, 0, sizeof(pList));
memset(coun, 0, sizeof(coun));
memset( output, 0, sizeof(output));
ArcNode *temp;
for(i = 0; i < m; ++i)//构造边链表
{
cin>>u>>v;//读入边的起点和终点
u--,v--;
coun[v]++;
temp = new ArcNode;
temp->data = v;
temp->pnext = NULL;//构造邻接表
if(pList[u] == NULL)//此时边链表中没有边结点
pList[u] = temp;
else//边链表中已经有边结点,插入temp
{
temp->pnext = pList[u];
pList[u] = temp;
}
}
TopSort();
for(i = 0; i < n; ++i)//释放边链表上各边结点所占用的存储空间
{
temp = pList[i];
while( temp != NULL )
{
pList[i] = temp->pnext;
delete temp;
temp = pList[i];
}
}
}
return 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
*/