poj1270_toposort+回溯
题意:给定一串字符(互异),再给出一个字符序列,表示一种前后关系,如abefcd,表示a<b,e<f,c<d。
将开始给出的字符进行排序,使之符合这个关系序列。并按字典序输出这些符合要求的字符序列。例如:
a b f g
a b b f 结果是:
abfg
abgf
agbf
gabf
分析:这题就是一个给定部分顺序,来确定整体顺序的拓扑排序。但一般的拓扑排序只找出一种符合要求的序列,这题要求找出所有符合要求的序列,这就有点困难,所以还得加上回溯算法。最后对求出的所有符合要求的序列进行排序输出就可以了。
代码:
每次写递归都TM有种向吐血的赶脚!!!
View Code
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include<map> 5 #include <algorithm> 6 using namespace std; 7 //toposort+回溯 8 //188K 16MS 9 const int maxnum=26; 10 bool graph[maxnum][maxnum]; 11 int indegree[maxnum]; 12 char str[maxnum]; 13 char ans[maxnum]; 14 map<char,int>hash; 15 int res; 16 17 void toposort(int depth) 18 { 19 if(depth==res) 20 { 21 printf("%s\n",ans); 22 return; 23 } 24 int i,j; 25 for(i=0;i<res;i++) 26 { 27 if(indegree[i]==0) 28 { 29 indegree[i]--; 30 ans[depth]=str[i]; 31 for(j=0;j<res;j++) 32 if(graph[i][j]) 33 indegree[j]--; 34 toposort(depth+1); 35 indegree[i]++; 36 for(j=0;j<res;j++) 37 if(graph[i][j]) 38 indegree[j]++; 39 } 40 } 41 } 42 43 int main() 44 { 45 char temp[55]; 46 int i,len,k,flag; 47 char c1,c2; 48 while(gets(temp)) 49 { 50 memset(graph,false,sizeof(graph)); 51 memset(indegree,0,sizeof(indegree)); 52 len=strlen(temp); 53 k=0; 54 for(i=0;i<len;i++) 55 if(temp[i]>='a' && temp[i]<='z') 56 { 57 str[k++]=temp[i]; 58 } 59 sort(str,str+k); //这样保证按字典顺序输出 60 res=k; //这里弄错了 61 for(i=0;i<len;i++) 62 hash[str[i]]=i; 63 gets(temp); 64 len=strlen(temp); 65 flag=0; 66 for(i=0;i<len;i++) 67 if(temp[i]>='a'&&temp[i]<='z') 68 { 69 if(flag==0) 70 { 71 c1=temp[i]; 72 flag=1; 73 } 74 else 75 { 76 c2=temp[i]; 77 graph[hash[c1]][hash[c2]]=true; 78 indegree[hash[c2]]++; 79 flag=0; 80 } 81 } 82 memset(ans,0,sizeof(ans));//这里一开始没加,wa了 83 toposort(0); 84 printf("\n"); 85 } 86 return 0; 87 }