题目:排序
思路:
拓扑排序。
每一次输入都根据大小关系建图。
如果此图有环,就是矛盾。
如果此图无环且每次拓扑排序都只能找到一个入度为0的点,就说明可以确定顺序。
否则不能确定。
注意:
当输入x<y时,如果此时矛盾了,不能先输出“不能判断”。
也就是说当拓扑排序找到两个及以上入度为0的点时,不能直接return,而要先打上标记,当已经确定没有矛盾十,才能输出不能判断。
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <cstring>
#include <map>
using namespace std;
int n,m;
int a[30][30]= {0};
int g[30][30]= {0};
int top(int id) {
int b[30]= {0};
vector<char> ord;
bool flag=true;
while(true) {
vector<int> c;
for(int i=1; i<=n; i++) {
if(!g[i][0]&&!b[i]) {
ord.push_back(char(i+'A'-1));
c.push_back(i);
b[i]=true;
}
}
if(c.size()>1) flag=false; //不能写 return 0;
if(!c.size()) break;
for(int i=0; i<c.size(); i++) {
for(int j=1; j<=n; j++) {
if(g[j][c[i]]) {
g[j][c[i]]=0;
g[j][0]--;
}
}
}
}
for(int i=1; i<=n; i++) {
if(g[i][0]) return -1;
}
if(!flag) return 0;
printf("Sorted sequence determined after %d relations: ",id);
for(int i=0; i<ord.size(); i++) printf("%c",ord[i]);
printf(".\n");
return 1;
}
int main() {
scanf("%d%d",&n,&m);
int ans=0;
for(int i=1; i<=m; i++) {
char x,y;
while(~scanf("%c",&x)&&!isalpha(x));
while(~scanf("%c",&y)&&!isalpha(y));
if(!a[y-'A'+1][x-'A'+1]) {
a[y-'A'+1][0]++;
a[y-'A'+1][x-'A'+1]=1;
}
memcpy(g,a,sizeof(a));
ans=top(i);
if(ans==-1) {
printf("Inconsistency found after %d relations.\n",i);
}
if(ans==0) continue;
break;
}
if(!ans) printf("Sorted sequence cannot be determined.\n");
return 0;
}