POJ1270 Following Orders(拓扑排序+回溯)

题意:

给出一些字母和这些字母之间的大小关系,要求输出所有满足大小的序列。

要点:

这题其实跟拓扑排序关系不是很大了,主要是输出所有序列比较麻烦,注意题目要求要输出所有的字母,也即是没有在大小关系中出现的字母可以插在任意位置上。我们可以这么想:所有当前入度为0的点可以作为起点,假设一个点的入度为3,说明它的前面起码有3个字母,每次dfs递归深度,寻找下一个入度为0的点,最后再回溯即可。

16128464 Seasonal 1270 Accepted 172K 0MS C++ 1302B 2016-09-27 19:52:09
#include<iostream>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
const int N = 25;
bool graph[N][N];
char str[N], ans[N];
int indegree[N];
int res;
map<char,int> num;

void toposort(int depth)
{
	if (depth == res)//题目中所有字母都会出现
	{
		printf("%s\n", ans);
		return;
	}
	for (int u = 0; u < res; u++)
	{
		if (indegree[u] == 0)//入度为0说明可以以当前点为起点
		{
			indegree[u]--;
			ans[depth] = str[u];
			for(int v=0;v<res;v++)
				if (graph[u][v])
					indegree[v]--;
			toposort(depth + 1);
			indegree[u]++;			//回溯
			for (int v = 0; v<res; v++)
				if (graph[u][v])
					indegree[v]++;
		}
	}
}

int main()
{
	char temp[55];
	while(gets_s(temp))
	{
		memset(graph, false, sizeof(graph));
		memset(indegree, 0, sizeof(indegree));
		int len = strlen(temp);
		res = 0;
		for (int i = 0; i < len; i++)
			if (isalpha(temp[i]))
				str[res++] = temp[i];
		sort(str, str + res);		//确保按照字典序输出
		for (int i = 0; i < res; i++)
			num[str[i]] = i;
		gets_s(temp);
		len = strlen(temp);
		int flag = 0;
		int c1, c2;
		for (int i = 0; i < len; i++)
		{
			if (isalpha(temp[i]))
			{
				if (flag == 0)
				{
					c1 = num[temp[i]];
					flag = 1;
				}
				else
				{
					c2 = num[temp[i]];
					graph[c1][c2] = true;
					indegree[c2]++;
					flag = 0;
				}
			}
		}
		memset(ans, 0, sizeof(ans));
		toposort(0);
		printf("\n");
	}
	return 0;
}


posted @ 2016-09-27 20:08  seasonal  阅读(152)  评论(0编辑  收藏  举报