Sorting It All Out poj-1094
题目大意:给出一些字符串之间的大小关系,问能否得到一个唯一的字符串序列,满足权值随下标递增。
注释:最多26个字母,均为大写。
想法:显然,很容易想到用toposort处理,对于每一个刚刚读入的大小关系,我们对进行一次拓扑排序,由于点数最多是26,所以总时间复杂度是$10^2$的。然后通过题面,可以发现第一个和第三个判定依据是可以中途退出的,而第二个条件是必须最后才可以判断的。但是由于poj的多组数据,我们必须要将所有的数据都读入完毕才能达到题目要要求。
最后,附上丑陋的代码... ...
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; int map[27][27],indegree[27],q[27]; int TopoSort(int n) //拓扑排序 { int c=0,temp[27],loc,m,flag=1,i,j; ////flag=1:有序 flag=-1:不确定 for(i=1;i<=n;i++) temp[i]=indegree[i]; for(i=1;i<=n;i++) { m=0; for(j=1;j<=n;j++) if(temp[j]==0) { m++; loc=j; } //查找入度为零的顶点个数 if(m==0) return 0; //有环 if(m>1) flag=-1; // 无序 q[c++]=loc; //入度为零的点入队 temp[loc]=-1; for(j=1;j<=n;j++) if(map[loc][j]==1) temp[j]--; } return flag; } int main() { int m,n,i,sign; //当sign=1时,已得出结果 char str[5]; while(scanf("%d%d",&n,&m)) { if(m==0&&n==0) break; memset(map,0,sizeof(map)); memset(indegree,0,sizeof(indegree)); sign=0; for(i=1;i<=m;i++) { scanf("%s",str); if(sign) continue; //一旦得出结果,对后续的输入不做处理 int x=str[0]-'A'+1; int y=str[2]-'A'+1; map[x][y]=1; indegree[y]++; int s=TopoSort(n); if(s==0) //有环 { printf("Inconsistency found after %d relations. ",i); sign=1; } if(s==1) //有序 { printf("Sorted sequence determined after %d relations: ",i); for(int j=0;j<n;j++) printf("%c",q[j]+'A'-1); printf(". "); sign=1; } } if(!sign) //不确定 printf("Sorted sequence cannot be determined. "); } return 0; }
小结:toposort还是很有用的。