Poj1094 Sorting It All Out (拓扑排序)

题目链接:http://poj.org/problem?id=1094

 

题意:给出n个元素,然后是边续的m个排列,其形式为A<B,表示元素A小于元素B,问多少个排列之后第一次出现下列某种情况,1得到全序,2得到矛盾;如果所有序列之后还不出现上述两种情况,则不能得到全序.

 

用拓扑排序解决,全序的话,如果求拓扑序列的过程中,整个栈中元素个数不超过1并且遍历了全体元素则得到全序.如果不能遍历所有元素,则出现环.

 

代码:

#include<stdio.h> #include<string.h> #define M 128 #define N 1024 typedef struct talE{ char v; talE *next; }Edge; Edge edg[N]; Edge *head[M]; int degree[M]; int dd[M]; int n,m,flag,e; char stk[M],top,ans[M],l; char mark[M]; void AddEdge(char u,char v) { edg[e].v=v;edg[e].next=head[u]; head[u]=&edg[e++]; } void Run(char c) {//如果已经严格排序,则同一时间栈中只存在一个元素 char i,ff=true; Edge *tmp; memmove(dd,degree,sizeof(degree)); top=0; for(i='A';i<'A'+n;i++){ if(!dd[i]) stk[top++]=i; } l=0;if(top>1) ff=false; while(top){ ans[l++]=stk[--top]; for(tmp=head[ans[l-1]];tmp;tmp=tmp->next){ if(!--dd[tmp->v]) stk[top++]=tmp->v; } if(top>1) ff=false; } if(l<c) flag=1; else if(ff&&l==n) flag=2; } int main() { int k; char u,v,c; //freopen("data1.in","r",stdin); while(scanf("%d%d",&n,&m),n||m){ flag=0; e=0;memset(head,NULL,sizeof(head)); memset(degree,0,sizeof(degree)); memset(mark,0,sizeof(mark)); k=0;c=0; while(m--){ getchar(); scanf("%c<%c",&u,&v); if(flag) continue; if(!mark[u]) c+=mark[u]=1; if(!mark[v]) c+=mark[v]=1; k++;AddEdge(u,v); degree[v]++;Run(c); } switch(flag){ case 0:puts("Sorted sequence cannot be determined.");break; case 1:printf("Inconsistency found after %d relations./n",k);break; case 2:printf("Sorted sequence determined after %d relations: ",k); for(u=0;u<l;putchar(ans[u]),u++);puts("."); } } return 0; } 

你可能感兴趣的:(c,struct,null,sorting)