您的位置:首页 > 理论基础 > 计算机网络

AOV网络与拓扑(二)——实现

2014-04-05 17:04 302 查看
例:对于输入的有向图进行拓扑排序,并输出一个拓扑有序序列;如果存在有向环,则给出提示信息。

首先输入顶点个数n和边数m;然后输入每条边<u,v>,输入0 0结束;顶点序号从1开始记起。

样例输入:

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!

分析:

样例中第一组测试数据描述的有向图:



样例中第二组测试数据描述的有向图:


存在有向回路的AOV网络。

下面奉上具体实现~

Code:

#include<iostream>
using namespace std;

#define MAX 10			//顶点个数的最大值

struct ArcNode
{
int to;
struct ArcNode *next;
};

int n, m;				//顶点个数、边数
ArcNode *List[MAX];		//每个顶点的边链表表头指针
int count[MAX];			//各顶点的入度
char output[100];		//输出内容

void TopSort()
{
int i, top = -1;
ArcNode *temp;
bool bcycle = false;	//是否存在有向环的标志
int pos = 0;			//写入output数组的位置
for(i = 0; i < n; i++)	//入度为0的顶点入栈
{
if(count[i] == 0)
{
count[i] = top;
top = i;
}
}
for(i = 0; i < n; i++)
{
if(top == -1)		//栈为空,存在有向回路
{
bcycle = true;
break;
}
else
{
int j = top; top = count[top];		//栈顶顶点j出栈
pos += sprintf(output+pos, "%d ", j+1);
temp = List[j];
//遍历顶点j的边链表,每条出边的终点的入度减1
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
{
output[pos-1] = '\n';	//去掉最后的空格
printf(output);
}
}
int main()
{
int i, u, v;		//循环变量、边的起点和终点
while(1)
{
scanf("%d%d", &n, &m);	//读入顶点个数、边数
if(n == 0 && m == 0) break;
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;
}


运行结果:



Ps:如有Bug,欢迎拍砖~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ 算法 网络 AOV