题目大意:给你n个大写字母(从A开始往后数n-1个)和m组字母之间的关系(X<Y表示X在Y的前面),让你判断这些字母之间先后关系:
(1)k组关系后(k<=m)若能判断出n个字母之间的先后关系,那么输出这个序列;
(2)k组关系后(k<=m)若判断出有相互矛盾的关系存在,那么输出错误;
(3)m组关系后若仍不能判断n个字母之间的关系,那么就输出否。
分析:很明显的拓扑排序,但我们要先明确这3个输出的优先级:(2)的优先级最高,其次是(1),(3)的优先级最低。原因很简单,首先(1)(2)不一定需要遍历这m组关系,而且我们在找出正确关系的过程中若发现矛盾(即判断出了(2)),那么就不再执行(1)了。
拓扑排序的模板很多,下面我分别用了可达矩阵和STL容器类两种方法:
可达矩阵实现代码如下:
#include <cstdio> #include <iostream> #include <cstring> using namespace std; int edge[30][30],ind[30]; int seq[30]; int Top_sort(int n) { int d[30],dnum,d0;//d[]用来存放当前情况下的顶点入度,dnum表示入度为0的个数,d0表示入度为0的顶点的编号 int cnt=0; int flag=1; for(int i=0;i<n;i++) d[i]=ind[i]; for(int i=0;i<n;i++) { dnum=0; for(int j=0;j<n;j++) if(d[j]==0) { dnum++; d0=j; } if(dnum==0) return -1; if(dnum>1) flag=0; seq[cnt++]=d0; d[d0]=-1; for(int j=0;j<n;j++) if(edge[d0][j]) d[j]--; } return flag; } int main() { int m,n; while(scanf("%d%d",&n,&m)) { if(m==0&&n==0) break; char u,c,v; bool flag=false; memset(edge,0,sizeof(edge)); memset(ind,0,sizeof(ind)); for(int i=1;i<=m;i++) { cin>>u>>c>>v; if(flag) continue; u-='A'; v-='A'; edge[u][v]=1; ind[v]++; int cnt=Top_sort(n); if(cnt==1) { printf("Sorted sequence determined after %d relations: ",i); for(int j=0;j<n;j++) printf("%c",seq[j]+'A'); printf(".\n"); flag=true; } if(cnt==-1) { printf("Inconsistency found after %d relations.\n",i); flag=true; } } if(!flag) puts("Sorted sequence cannot be determined."); } return 0; }
用STL中vector容器类和queue的实现代码如下:
#include <cstdio> #include <iostream> #include <cstring> #include <vector> #include <queue> using namespace std; vector <int> edge[30]; int indgree[30],seq[30]; int Top_sort(int n) { queue<int> que; int ind[30]; int tmp=0; bool res=false; for(int i=0;i<n;i++) { ind[i]=indgree[i]; if(ind[i]==0) que.push(i); } while(!que.empty()) { if(que.size()>1) res=true; int cnt=que.front(); que.pop(); seq[tmp++]=cnt; for(int i=0;i<edge[cnt].size();i++) { ind[edge[cnt][i]]--; if(ind[edge[cnt][i]]==0) que.push(edge[cnt][i]); } } if(tmp<n) return -1; if(res) return 0; return 1; } int main() { int n,m,i; char u,c,v; while(scanf("%d%d",&n,&m)) { if(n==0&&m==0) break; memset(indgree,0,sizeof(indgree)); int flag; bool judge=0; for(i=0;i<=30;i++) edge[i].clear(); for(i=1;i<=m;i++) { cin>>u>>c>>v; if(judge) continue; u-='A'; v-='A'; edge[u].push_back(v); indgree[v]++; flag=Top_sort(n); if(flag==-1) { printf("Inconsistency found after %d relations.\n",i); judge=1; } else if(flag==1) { printf("Sorted sequence determined after %d relations: ",i); for(int k=0;k<n;k++) printf("%c",seq[k]+'A'); printf(".\n"); judge=1; } } if(!judge) puts("Sorted sequence cannot be determined."); } return 0; }