算法提高 士兵排队问题(拓扑排序的队列解法)
算法提高 士兵排队问题
时间限制:1.0s 内存限制:256.0MB
试题
有N个士兵(1≤N≤26),编号依次为
A,B,C,…,队列训练时,指挥官要把一些士兵从高到矮一次排成一行,但现在指挥官不能直接获得每个人的身高信息,只能获得“P1比P2高”这样的比较
结果(P1、P2∈A,B,C,…,Z,记为 P1> P2),如”A> B”表示A比B高。
请编一程序,根据所得到的比较结果求出一种符合条件的排队方案。
(注:比较结果中没有涉及的士兵不参加排队)
输入要求
比较结果从文本文件中读入(文件由键盘输入),每个比较结果在文本文件中占一行。
输出要求
若输入数据无解,打印“No Answer!”信息,否则从高到矮一次输出每一个士兵的编号,中间无分割符,并把结果写入文本文件中,文件由键盘输入:
样例输入
A>B
B>D
F>D
样例输出
AFBD
1 /* 2 问题 拓扑排序 3 解题思路 使用队列的拓扑排序解法 4 坑点 1、注意吃掉换行 2、注意字符和数字的转换 3、写的时候注意用一种全覆盖的方法 5 4、No answer!中间只有一个空格,输入关系中一个大写字母加“>”号加一个大写字母 6 5、输入存在重复边,注意不要增加重复的入度 7 */ 8 #include<cstdio> 9 #include<iostream> 10 #include<queue> 11 #include<cstring> 12 #include<vector> 13 using namespace std; 14 15 16 17 int cou,map[31][31],book[31],deg[31]; 18 vector<char> ans; 19 int toposort(); 20 21 int main() 22 { 23 char u,v; 24 memset(map,0,sizeof(map)); 25 memset(deg,0,sizeof(deg)); 26 int i; 27 cou=0; 28 while(scanf(" %c>%c",&u,&v) != EOF){ 29 //cout<<u<<"->"<<v<<endl; 30 if( map[u - 'A'][v - 'A'] ) continue;//重复的边跳过 31 map[u - 'A'][v - 'A']=1; 32 book[u - 'A']=book[v - 'A']=1;//该字母出现 33 deg[v - 'A']++; 34 } 35 36 /*for(i=0;i<31;i++){ 37 if(book[i]) 38 printf("%c的入度为%d\n",i+'A',deg[i]); 39 } 40 for(i=0;i<31;i++){ 41 if(book[i]) 42 printf("%c出现过\n",i+'A'); 43 }*/ 44 ans.clear(); 45 if(toposort()){ 46 for(i=0;i<ans.size();i++){ 47 printf("%c",ans[i]); 48 } 49 printf("\n"); 50 } 51 else 52 printf("No Answer!\n"); 53 return 0; 54 } 55 56 int toposort() 57 { 58 queue<int> q; 59 int x,t=0,i,j; 60 for(i=0;i<31;i++){ 61 if(book[i]){ 62 cou++; 63 if(deg[i] == 0) //出现过且入度为0 64 q.push(i); 65 } 66 } 67 68 while(!q.empty()){ 69 x=q.front(); 70 q.pop(); 71 t++; 72 ans.push_back(x + 'A'); 73 //printf("%c\n",x + 'A'); 74 75 for(i=0;i<31;i++){ 76 if(book[i] && map[x][i]){ 77 deg[i]--; 78 if(deg[i] == 0) 79 q.push(i); 80 } 81 } 82 } 83 84 if(t == cou) return 1; 85 return 0; 86 }
欢迎交流,共同进步——