现在的位置: 首页 > 综合 > 正文

POJ 1094 Sorting It All Out (拓扑排序)

2018年01月14日 ⁄ 综合 ⁄ 共 1446字 ⁄ 字号 评论关闭

题目类型  拓扑排序

题目意思
给出 n (2 <= n <= 26) 个大写字母和 m 个关系 每个关系形是"A<B"这样的格式
现在从第1个关系按顺序往后看 如果到第 i 个关系时出现矛盾则输出在第 i 个关系后矛盾了 如果到第 i 个关系时大写字母的顺序已经唯一确定那么输出确定后的序列 如果到最后依然没唯一确定顺序输出不能确定顺序

解题方法
直接按照题目意思每输入一个关系判断一下就行了
参考代码 - 有疑问的地方在下方留言 看到会尽快回复的
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>

using namespace std;

const int maxn = 1000;

char str[maxn][10];
vector<int>M[30];
int res[30], num[30], n, tm[30];
bool vis[30];

int topo() {
	queue<int>q;
	int tn = 0;
	for( int i=0; i<26; i++ ) {
		if(num[i] == 0 && vis[i]) q.push(i);
		if(vis[i]) tn++;
		tm[i] = num[i];
	}
	int cnt = 0;
	int flag = 0;
	while(!q.empty()) {
		if(q.size() > 1) flag = 1; // 出现两个以上入度为0的点则没确定唯一顺序
		int f = q.front(); q.pop();
		res[cnt++] = f;
		for( int i=0; i<M[f].size(); i++ ) {
			tm[M[f][i]]--;
			if(tm[M[f][i]] == 0) q.push(M[f][i]);
		}
	}
	if(cnt == n) { // 完成排序
		if(flag == 0) return 2; //唯一排序
		else return 1;
	}
	else if(cnt != tn) return 0; //没完成排序即有冲突
	else return 1; //没有唯一的顺序
}

int main() {
	freopen("in", "r", stdin);
	int m;
	while(scanf("%d%d", &n, &m), n || m) {
		for( int i=0; i<26; i++ ) num[i] = 0, M[i].clear();
		memset(vis, 0, sizeof(vis));
		bool flag = true;
		for( int i=0; i<m; i++ ) {
			scanf("%s", str[i]);
			if(flag == false) continue;
			num[str[i][2]-'A']++;
			M[str[i][0]-'A'].push_back(str[i][2]-'A');
			vis[str[i][0]-'A'] = vis[str[i][2]-'A'] = true;
			int tmp = topo();
			if(tmp == 0) {
				flag = false;
				printf("Inconsistency found after %d relations.\n", i+1);
			}
			else if(tmp == 2) {
				flag = false;
				printf("Sorted sequence determined after %d relations: ", i+1);	
				for( int j=0; j<n; j++ ) printf("%c", res[j]+'A');
				printf(".\n");
			}
		}
		if(flag == false) continue;
		printf("Sorted sequence cannot be determined.\n");
	}
	return 0;
}

抱歉!评论已关闭.