拓扑排序

余生颓废 提交于 2019-11-29 11:55:47

拓扑排序

类似于a<b,c<b,d<c,可以找到一个关系是a<d<c<b。意思就是有好几件事ABCD,B要在A后面做,C要在B后面做等等,然后对每个事件的先后顺序进行排序。

做法就是每次删除一个入度为零的点,而这个点指向的点的入度就减一,循环下去直到所有结点被找出来。如果排序失败,表示有环。

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<cmath>
#include<cstring>
#define MAXN 517
using namespace std;

int G[MAXN][MAXN];
int ds[MAXN];
int ans[MAXN];
int n, m, x, y;
int i, j;

void tp();
void init();

int main()
{
	while (cin >> n >> m)
	{
		init();
		for (i = 0;i < m;i++)
		{
			cin >> x >> y;
			G[x][y] = 1;
		}
		tp();
		for (i = 1;i < n;i++)
		{
			cout << ans[i] << ' ';
		}
		cout << ans[n] << endl;
	}
}

void tp()
{
	for (i = 1; i <= n; i++)
	{
		for (j = 1; j <= n; j++)
		{
			if (G[i][j])
			{
				ds[j]++;   //记录每个结点的入度
			}
		}
	}

	for (int i = 1;i <= n;i++)
	{
		int k = 1;
		while (ds[k] != 0) //找到入度为零的点
		{
			k++;
		}
		ans[i] = k;  //该点进排序列
		ds[k] = -1;  
		for (int j = 1;j <= n;j++) //该点指向的点的入度都减一
		{
			if (G[k][j])
			{
				ds[j]--;
			}
		}
	}
}

void init()
{
	memset(ds, 0, sizeof(ds));
	memset(ans, 0, sizeof(ans));
	memset(G, 0, sizeof(G));
}


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!