题目类型 拓扑排序
题目意思
给出 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; }