uva124:http://uva.onlinejudge.org/index.php?option=onlinejudge&page=show_problem&problem=60
题意: 第一行给出字符串(小写字母),表示出现的字符类型第二行是约束关系,a1 b1 a2 b2 a3 b3.....ai bi,表示ai必须在bi前面按照字典序输出所有满足约束条件的序列
题解:题解:由题意会想到用拓扑排序,但是题目要求是字典序输出,所以可以用dfs来处理。
1 #include<algorithm> 2 #include<cstring> 3 #include<cstdio> 4 #include<iostream> 5 #include<vector> 6 #include<iterator> 7 #include<string> 8 using namespace std; 9 char map[27];//储存原图 10 int g[27][27];//topsort的图 11 bool visit[27];//标记已经出现的字母 12 int counts[27];//记录出现过字母的入度 13 int num;//出现的字母的个数 14 vector<char> ans;//储存字母序列 15 void init(){//初始化 16 num=0; 17 memset(g,0,sizeof(g)); 18 memset(visit,0,sizeof(visit)); 19 memset(counts,0,sizeof(counts)); 20 memset(map,0,sizeof(0)); 21 } 22 void dfs(int depth,int count){ 23 if(depth>=count){//如果当前的字母个数已经达到num,则可以输出然后返回。 24 copy(ans.begin(), ans.end(), ostream_iterator<char>(cout)); 25 cout<<endl; 26 return; 27 } 28 for(int i=1;i<27;i++){//否则查找下一个字母 29 if(visit[i]){//如果该字母已经出现过则,进入 30 if(counts[i]==0){ 31 counts[i]=-1; 32 ans.push_back(i+'a'-1);//把当前点加入结果中 33 for(int j=1;j<27;j++){//把与此点相关的边删去 34 if(g[i][j]==1){ 35 counts[j]--; 36 } 37 } 38 dfs(depth+1,count);//递归往下 39 ans.pop_back();//记得恢复现场1,结果集的删除以及入度的增加 40 counts[i]=0; 41 for(int k=1;k<27;k++){ 42 if(g[i][k]==1){ 43 counts[k]++; 44 } 45 } 46 } 47 } 48 } 49 } 50 51 int main(){ 52 string line ; 53 int aa=0; 54 while(getline(cin,line)){//读取一行 55 init(); 56 int len=line.length(); 57 for(int i=0;i<len;i+=2){//标记出现过的字母以及个数 58 visit[line[i]-'a'+1]=true; 59 num++;} 60 getline(cin,line);//读取第二行 61 int len1=line.length(); 62 for(int i=0;i<len1;i+=4){//建图 63 g[line[i]-'a'+1][line[i+2]-'a'+1]=1; 64 counts[line[i+2]-'a'+1]++; 65 } 66 if(aa) 67 printf(" ");//注意这里的处理,如果是在poj上,你在每次结果后面直接打空行可以 68 dfs(0,num);//但是如果在uva上,就会wa,因为在uva上的判断是两组之间打空行,多余空行算错 69 aa=1; 70 71 } 72 73 }