Sorting It All Out POJ - 1094 拓扑排序

时间:2021-01-31 13:21:54

题意:给N个字母,和M个偏序关系 求一个可确定的全序,可确定是指没有其他的可能例如A>B D>B 那么有ADB DAB两种,这就是不可确定的
其中,M个偏序关系可以看做是一个一个按时间给出的,如果还没给完就已经满足条件了,后面的可以不用管

题解:拓扑水题,直接用拓扑排序暴力 其中 如果途中 冲突 那么即使后面添加了也不能改变冲突 如果前面成功了那就不用管后面了直接continue 其中
拓扑判断的时候如果存在多个0度点 那么就不可确定 如果排序完比n个点少,那么确定不了一个全序,分类讨论

#include<cstdio>
#include<iostream>
using namespace std;
int seq[];
int n,m;
int err,ans;
struct Node{
int pos,next;
}edge[];
int neigh[];
int queue[];
int cur,indegree[];
int front=,rear=;
int toposort(){
int indge[];
bool ok=;
for(int i=;i<n;i++){
indge[i]=indegree[i];
if(indge[i]==)queue[rear++]=i;
}
int k=;
while(front!=rear){
if(front+<rear)ok=;
int temp=queue[front++];
seq[k++]=temp;
int e=neigh[temp];
while(e!=-){
--indge[edge[e].pos];
if(indge[edge[e].pos]==)queue[rear++]=edge[e].pos;
e=edge[e].next;
} }
if(k<n)return -;//huan
if(ok)return ;//chongfu
return ;//chenggong
}
int main(){
char s[];
while(cin>>n>>m&&n){
for(int i=;i<n;i++){
indegree[i]=;
neigh[i]=-;
}
cur=;
err=ans=-;
for(int i=;i<m;i++){
cin>>s;
if(err!=-||ans!=-)continue;//已经有结果了直接把后面的直接读掉就行
int temp1=s[]-'A',temp2=s[]-'A';
edge[cur].pos=temp2;
edge[cur].next=neigh[temp1];//链表记录表相邻
neigh[temp1]=cur;
cur++;
indegree[temp2]++;
int res=toposort();
if(res==)ans=i+;
else if(res==-)err=i+;
}
if(ans!=-){
printf("Sorted sequence determined after %d relations: ", ans);
for (int i = ; i < n; ++i) putchar('A' + seq[i]);
printf(".\n"); }
else if(err!=-){
printf("Inconsistency found after %d relations.\n", err);
}
else {
printf("Sorted sequence cannot be determined.\n"); } }
return ;
}