POJ T1094 Sorting It All Out
前言:
开头还是照常操作,自己实在是菜。这道题题意很容易懂,那么难在哪里呢?(应该只有鄙人觉得难......)
1.每接收一次关系,就要进行拓扑一次。
2.下手前想清楚,三种结果对应的判断条件。
鄙人就是第二点卡了很久,可能心态有点不好,分析问题不够冷静和独立,emmmmmm
题解:
我就拿题目给的三种情况的前后顺序分别对应flag = 1,flag = 2,flag = 3;
三种情况的优先级 2 > 1 > 3
1.Sorted sequence determined after xxx relations: yyy...y.
这第一种情况,只要前面没有第三种情况,已确定关系就直接输出。
3.Inconsistency found after xxx relations.
如果出现了第三种情况,那么此组数据矛盾,也就不需要判断第一种情况,所以在代码中一旦cnt == 0那么就直接返回3,输出第三种结果。
2.Sorted sequence cannot be determined.
这第二种情况,是在所有关系都输入完毕后,还不能确定所有点的关系,则输出此种情况。
所以定义了flag,来判断在m次循环中是否进行了1或3这两种情况。
所以三种情况的优先级就是如上。
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
const int MAXN = 30;
int n,m;
int indeg[MAXN],indegr[MAXN];
bool flag;
char outp[MAXN];
vector<int> edge[MAXN];
void init(){
flag = false;
memset(indeg,0,sizeof(indeg));
for(int i = 0; i < n; ++i) edge[i].clear();
}
int topsort(){
int cnt,now,flag = 1;
memset(outp,'\0',sizeof(outp));
for(int i = 0; i < n; ++i) indegr[i] = indeg[i];
for(int i = 0; i < n; ++i){
cnt = now = 0;
for(int j = 0; j < n;++j)
if(indegr[j] == 0){
cnt++;now = j;
}
if(cnt == 0) return 3;
if(cnt > 1) flag = 2;
outp[i] = now + 'A';
indegr[now]--;
for(int j = 0; j < edge[now].size();++j)
indegr[edge[now][j]]--;
}
return flag;
}
int main(){
char ch[4];
while(scanf("%d%d",&n,&m),n+m){
init();
for(int i = 1; i <= m; ++i){
scanf("%s",ch);
if(flag) continue;
edge[ch[0] - 'A'].push_back(ch[2] - 'A');
indeg[ch[2] - 'A']++;
int ind = topsort();
if(ind == 1){
printf("Sorted sequence determined after %d relations: %s.\n",i,outp);
flag = true;
}
if(ind == 3){
printf("Inconsistency found after %d relations.\n",i);
flag = true;
}
}
if(!flag) printf("Sorted sequence cannot be determined.\n");
}
return 0;
}