Sorting It All Out
Description An ascending sorted sequence of distinct values is one in which some form of a less-than operator is used to order the elements from smallest to largest. For example, the sorted sequence A, B, C, D implies that A < B, B < C and C < D. in this problem, we will give you a set of relations of the form A < B and ask you to determine whether a sorted order has been specified or not.
Input Input consists of multiple problem instances. Each instance starts with a line containing two positive integers n and m. the first value indicated the number of objects to sort, where 2 <= n <= 26. The objects to be sorted will be the first n characters of the uppercase alphabet. The second value m indicates the number of relations of the form A < B which will be given in this problem instance. Next will be m lines, each containing one such relation consisting of three characters: an uppercase letter, the character "<" and a second uppercase letter. No letter will be outside the range of the first n letters of the alphabet. Values of n = m = 0 indicate end of input.
Output For each problem instance, output consists of one line. This line should be one of the following three:
Sorted sequence determined after xxx relations: yyy...y. Sorted sequence cannot be determined. Inconsistency found after xxx relations. where xxx is the number of relations processed at the time either a sorted sequence is determined or an inconsistency is found, whichever comes first, and yyy...y is the sorted, ascending sequence. Sample Input 4 6 A<B A<C B<C C<D B<D A<B 3 2 A<B B<A 26 1 A<Z 0 0 Sample Output Sorted sequence determined after 4 relations: ABCD. Inconsistency found after 2 relations. Sorted sequence cannot be determined. Source |
题目大意:
给出一些字母和它们之间的偏序关系,让你来判断通过这些关系是否能构成唯一的升序序列。如果能,输出这个序列,并输出是通过前多少关系得出的(即使之后的关系引出矛盾也不必理会)。如果存在矛盾,则输出前多少项出现的矛盾的。如果输入完仍无法得出唯一关系,输出相关信息。
题目算法:
拓扑排序。
拓扑排序:若G包含有向边(U,V),则在序列中U出现在V之前,即该序列使得图中所有有向边均从左指向右。如果图是有回路的,就不存在这样的序列。
首先选择一个无前驱的顶点(即入度为0的顶点,图中至少应该有一个这样的顶点,否则肯定存在回路),然后从图中移去该顶点以及由其发出的所有有向边,如果图中还存在无前驱的顶点,则重复上述操作,直到操作无法进行。如果图不为空,说明图中存在回路,无法进行拓扑排序;否则移出的顶点的顺序就是对该图的一个拓扑排序。
具体思路:
每输入一组偏序关系进行一次拓扑排序。
如果存在回路,输出矛盾。
在不存在回路的基础上,判断每次入度为0的点是否唯一,只有保证每次只有一个点入度为0,才能保证最终的序列唯一。
注意:如果对于某一次输入已经能确定序列矛盾或者序列完全有序,则可以忽略后面的输入。
当入度为0的定点大于1时,直接return了,但之后可能出现回路即矛盾的情况。
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<stack> using namespace std; int n,m,indeg[30],vis[30]; vector<int> vt[30]; char res[30]; int TopoSort(){ stack<int> st; int flag=1; for(int i=0;i<n;i++){ vis[i]=indeg[i]; if(indeg[i]==0) st.push(i); } if(st.size()>1) flag=0; int cnt=0; while(!st.empty()){ int u=st.top(); st.pop(); res[cnt++]=(char)u+'A'; for(int i=0;i<vt[u].size();i++) if(--vis[vt[u][i]]==0) st.push(vt[u][i]); if(st.size()>1) flag=0; } res[cnt]='\0'; for(int i=0;i<n;i++) if(vis[i]) return -1; return flag && (cnt==n); } int main(){ //freopen("input.txt","r",stdin); char str[5]; int tag,flag,ans; while(~scanf("%d%d",&n,&m)){ if(n==0 && m==0) break; memset(indeg,0,sizeof(indeg)); for(int i=0;i<n;i++) vt[i].clear(); ans=tag=0; for(int i=1;i<=m;i++){ scanf("%s",str); vt[str[0]-'A'].push_back(str[2]-'A'); indeg[str[2]-'A']++; if(tag==0){ flag=TopoSort(); if(flag==-1){ ans=i; tag=-1; } if(flag==1){ ans=i; tag=1; } } } if(tag==1) printf("Sorted sequence determined after %d relations: %s.\n",ans,res); else if(tag==-1) printf("Inconsistency found after %d relations.\n",ans); else if(tag==0) printf("Sorted sequence cannot be determined.\n"); } return 0; }
一些练习:http://www.cnblogs.com/372465774y/category/424141.html
1 #include<iostream> 2 #include<string> 3 #include<cstdio> 4 #include<cstring> 5 6 using namespace std; 7 8 int deg[30],d[30],g[30][30],res[30]; 9 int n,m; 10 11 int Topo(string str){ 12 int x=str[0]-'A'; 13 int y=str[2]-'A'; 14 if(g[x][y]==0){ 15 g[x][y]=1; 16 d[y]++; 17 } 18 for(int i=0;i<n;i++) 19 deg[i]=d[i]; 20 int flag=1,len=0,tmp,cnt; 21 for(int i=0;i<n;i++){ 22 cnt=0; 23 for(int j=0;j<n;j++) 24 if(deg[j]==0){ 25 tmp=j; 26 cnt++; 27 } 28 if(cnt==0) 29 return -1; 30 else if(cnt>1) //这里不直接return 0;因为之后可能出现回路 31 flag=0; 32 deg[tmp]--; 33 res[len++]=tmp; 34 for(int j=0;j<n;j++) 35 if(g[tmp][j]==1) 36 deg[j]--; 37 } 38 return flag; 39 } 40 41 void Solve(){ 42 string str; 43 int flag=1; 44 for(int i=0;i<m;i++){ 45 cin>>str; 46 if(flag){ 47 int tmp=Topo(str); 48 if(tmp==1){ 49 cout<<"Sorted sequence determined after "<<i+1<<" relations: "; 50 for(int j=0;j<n;j++) 51 cout<<char(res[j]+'A'); 52 cout<<"."<<endl; 53 flag=0; 54 }else if(tmp==-1){ 55 cout<<"Inconsistency found after "<<i+1<<" relations."<<endl; 56 flag=0; 57 } 58 } 59 } 60 if(flag) 61 cout<<"Sorted sequence cannot be determined."<<endl; 62 } 63 64 int main(){ 65 66 //freopen("input.txt","r",stdin); 67 68 string str; 69 while(scanf("%d%d",&n,&m)){ 70 if(n==0 && m==0) 71 break; 72 if(n-1>m){ 73 for(int i=0;i<m;i++) 74 cin>>str; 75 cout<<"Sorted sequence cannot be determined."<<endl; 76 continue; 77 } 78 memset(g,0,sizeof(g)); 79 memset(d,0,sizeof(d)); 80 Solve(); 81 } 82 return 0; 83 }