题意描述:给定前n个字母的关系描述,根据输入的m组描述(类似A<B),判断能否唯一确定前n个字母的顺序,或者看能否出现矛盾,并且要求输出得出结论时共需用到前面多少组数据,或者最终不能确定顺序。
分析:每次添加一组关系就进行一次拓扑排序,看能否判断关系,或者得出矛盾;如果是不确定的关系就继续添加直到数据用完,或者得出结论。关于判定关系是不是唯一确定的只需要看拓扑排序过程中,每次去掉一个入度为0的点之后剩下的入度为0的点是否唯一,如果不是的话最终得出来的关系就是不唯一的。
代码:
#include <iostream> #include <sstream> #include <cstdio> #include <climits> #include <cstring> #include <cstdlib> #include <string> #include <map> #include <cmath> #include <vector> #include <queue> #include <algorithm> #define esp 1e-6 #define pb push_back #define mp(a, b) make_pair((a), (b)) #define in freopen("in.txt", "r", stdin); #define out freopen("out.txt", "w", stdout); #define print(a) printf("%d ",(a)); #define bug puts("********))))))"); #define stop system("pause"); #define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++) #define inf 0x0f0f0f0f using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int, int> pii; typedef vector<pii,int> VII; typedef vector<int>:: iterator IT; const int maxn = 30; VI g[maxn]; int du[maxn], L[maxn], vis[maxn]; int n, m, ok; bool check(void) { int ct = 0; for(int i = 0; i < n; i++) if(!du[i] && !vis[i]) { ct++; if(ct > 1) return false; } return true; } bool toposort(void) { memset(du, 0, sizeof(du)); for(int i = 0; i < n; i++) for(int j = 0; j < g[i].size(); j++) du[g[i][j]]++; ok = check(); queue<int> q; for(int i = 0; i < n; i++) if(!du[i]) q.push(i); int tot = 0; while(!q.empty()) { int x = q.front(); L[tot++] = x; vis[x] = 1; q.pop(); for(int j = 0; j < g[x].size(); j++) { int t = g[x][j]; du[t]--; if(!du[t]) q.push(t); } if(ok) ok = check(); } return tot == n; } int main(void) { while(scanf("%d%d", &n, &m), n||m) { int flag = 0; int k; char s[10]; for(int i = 0; i < maxn; i++) g[i].clear(); for(k = 1; k <= m; k++) { ok = 1; scanf("%s", s); int u, v; u = s[0] - 'A'; v = s[2] - 'A'; g[u].pb(v); memset(vis, 0, sizeof(vis)); if(!toposort()) { flag = 1; printf("Inconsistency found after %d relations. ", k); break; } else if(ok) { flag = 1; printf("Sorted sequence determined after %d relations: ", k); for(int i = 0; i < n; i++) putchar(L[i] + 'A'); puts("."); break; } } for(int i = k+1; i <= m; i++) scanf("%s", s); if(!flag && k > m) puts("Sorted sequence cannot be determined."); } return 0; }