UVa 872 - Ordering 输出全拓扑排序

本题要求输出所有拓扑排序的序列。

还好本题的数据量不是非常大。限制在26个大写英文字母,故此能够使用递归法输出。

这个递归输出所有解在Leetcode非常多这种题目的,不小心的话,还是非常难调试的。

整体考了递归和拓扑排序,还有推断能否够拓扑排序-就是是否图有环。

考了三大知识点。难度还是有的。由于数据量不大,故此推断环能够使用一般递归方法。递归仅仅须要注意细节就好了。


#include <stdio.h>
#include <vector>
#include <string.h>
using namespace std;
const int ALPHA = 26;
bool gra[ALPHA][ALPHA];
int id = 0, len = 0;
const int MAX_B = 512;
char buf[MAX_B];

char getFromBuf()
{
	if (id >= len)
	{
		len = fread(buf, 1, MAX_B, stdin);
		id = 0;
	}
	return buf[id++];
}

struct Subset
{
	int p, r;
};

Subset subs[ALPHA];

int findParent(int u)
{
	if (u != subs[u].p) subs[u].p = findParent(subs[u].p);
	return subs[u].p;
}

void unionTwo(int x, int y)
{
	int xroot = findParent(x);
	int yroot = findParent(y);
	if (subs[xroot].r < subs[yroot].r) subs[xroot].p = yroot;
	else
	{
		subs[yroot].p = xroot;
		if (subs[yroot].r == subs[xroot].r) subs[xroot].r++;
	}
}

void initSubs()
{
	for (int i = 0; i < ALPHA; i++)
	{
		subs[i].p = i;
		subs[i].r = 0;
	}
}

bool isCycle()
{
	initSubs();
	for (int i = 0; i < ALPHA; i++)
	{
		for (int j = 0; j < ALPHA; j++)
		{
			if (i == j || !gra[i][j]) continue;
			int ip = findParent(i);
			int jp = findParent(j);
			if (ip == jp) return true;
			unionTwo(i, j);
		}
	}
	return false;
}

int rs[ALPHA];
bool vis[ALPHA];
void printAllTopologicalOrders(int N, int rsid = 0)
{
	if (rsid == N)	//递归究竟了,打印结果
	{
		if (rsid > 0) putchar(rs[0]+'A');
		for (int i = 1; i < rsid; i++)
		{
			putchar(' ');
			putchar(rs[i]+'A');
		}
		putchar('\n');
		return ;
	}
	for (int i = 0; i < ALPHA; i++)
	{
		if (vis[i]) continue;//这里要推断,漏了这句。好难dubg啊。

要细致用脑去模拟过程才干发现!!

if (!gra[i][i]) continue; //没有这个点,跳过 int j = 0; for ( ; j < ALPHA; j++)//检查i是否有入度 { if (i != j && !vis[j] && gra[j][i]) break; } if (j == ALPHA) //找到入度为零的点i了 { vis[i] = true; rs[rsid] = i; printAllTopologicalOrders(N, rsid+1); vis[i] = false; } } } int main() { int T; scanf("%d", &T); while (T--) { int N = 0; memset(gra, 0, sizeof(gra)); char a = getFromBuf(); while ((a == '\n' || a == ' ') && len) a = getFromBuf(); while (a != '\n' && len) { if ('A' <= a && a <= 'Z') { gra[a-'A'][a-'A'] = 1;//代表有点 N++; } a = getFromBuf(); } while ((a == '\n' || a == ' ') && len) a = getFromBuf(); while (a != '\n' && len) { int u = a - 'A'; a = getFromBuf(); a = getFromBuf(); int v = a - 'A'; gra[u][v] = 1; a = getFromBuf(); if (a == '\n') break; a = getFromBuf(); } fill(vis, vis+ALPHA, false); if (isCycle()) puts("NO"); else { printAllTopologicalOrders(N); } if (T) putchar('\n'); } return 0; }



posted @ 2016-04-03 13:14  phlsheji  阅读(659)  评论(0编辑  收藏  举报