poj1094:http://poj.org/problem?id=1094
题解(一位大神的分析)
一、当输入的字母全部都在前n个大写字母范围内时:
(1)最终的图 可以排序: 在输入结束前如果能得到最终的图(就是用这n个字母作为顶点,一个都不能少);而且最终得到的图 无环;
只有唯一一个 无前驱(即入度为0)的结点,但允许其子图有多个无前驱的结点。在这步输出排序后,不再对后续输入进行操作
(2)输出矛盾:在输入结束前如果最终图的子图有环, 在这步输出矛盾后,不再对后续输入进行操作
(3)输出无法确认排序:这种情况必须全部关系输入后才能确定,其中又有2种可能
①最终图的字母一个不缺,但是有多个 无前驱结点
②输入结束了,但最终的图仍然字母不全,与 无前驱结点 的多少无关
二、当输入的字母含有 非前n个大写字母 的字母时(超出界限):
(1)输出矛盾:输入过程中检查输入的字母(结点),若 前n个大写字母 全部出现,则在最后一个大写字母出现的那一步 输出矛盾
(2)输出无法确认排序:最后一步输入后,前n个大写字母 仍然未全部出现,则输出 无法确认排序
PS:在使用“无前驱结点”算法时必须要注意,在“矛盾优 先”的规律下,必须考虑一种特殊情况,就是多个无前驱结点与环共存时的情况,即输入过程中子图都是有
多个无前驱结点,最后一步输入后出现了环,根据算法的特征,很容易输出“不能确认排序”,这是错的,必须适当修改算法,输出“矛盾”。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 int counts[26]; 8 int temp[26]; 9 char relation[3]; 10 char seq[26]; 11 bool alpha[26]; 12 int n,m; 13 vector<vector<char> >v; 14 int topsort(int s){ 15 int i,j,r,cnt; 16 bool flag; 17 r=0,cnt=0; 18 for( i=0;i<n;i++) 19 temp[i]=counts[i]; 20 flag=1; 21 while(s--){ 22 cnt=0; 23 for( i=0;i<n;i++){ 24 if(temp[i]==0){ 25 j=i;cnt++; 26 } 27 } 28 if(cnt>=1){ 29 if(cnt>1)flag=0; 30 for( i=0;i<v[j].size();i++) 31 temp[v[j][i]]--; 32 seq[r++]=j+'A'; 33 temp[j]=-1;seq[r]=0; 34 } 35 else if(cnt==0)return -1; 36 } 37 if(flag){return r;} 38 else 39 return 0; 40 } 41 int main(){ 42 int i,j,t,k,c; 43 int determined;char ss[26]; 44 while(~scanf("%d%d",&n,&m)&&n&&m){ 45 memset(counts,0,sizeof(counts)); 46 memset(alpha,false,sizeof(alpha)); 47 v.clear(); 48 v.resize(n); 49 c=0;determined=0; 50 for(i=0;i<m;i++){ 51 scanf("%s",relation); 52 counts[relation[2]-'A']++; 53 v[relation[0]-'A'].push_back(relation[2]-'A'); 54 if(!alpha[relation[0]-'A']){ 55 c++;alpha[relation[0]-'A']=true; 56 } 57 if(!alpha[relation[2]-'A']){ 58 c++;alpha[relation[2]-'A']=true; 59 } 60 if(determined==0){ 61 t=topsort(c); 62 if(t==-1){ 63 determined=-1;k=i+1; 64 } 65 else if(t==n){ 66 determined=1;k=i+1; 67 strcpy(ss,seq); 68 } 69 } 70 } 71 72 if(determined==-1) 73 printf("Inconsistency found after %d relations. ",k); 74 else if(determined==0) 75 printf("Sorted sequence cannot be determined. "); 76 else{ 77 printf("Sorted sequence determined after %d relations: %s. ",k,ss); 78 } 79 80 81 } 82 }