题解报告说是用拓扑排序,删边法求解。
但菜鸡的我还是不会做,
其实感觉还是dfs,但关键在与如何将约束条件实现,所以转而采用图的形式进行思考,约束条件即为有向边,并将每一个节点设置入度,入度为零的点自然先输出,接着将入度为零的点所连接的节点入度减一,再接着dfs,这样约束条件的问题就很好的解决了。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<cstring>
using namespace std;
bool graph[30][30];
int in[30];
char ans[30];
map<char,int> m;
int k;
char str[30];
void solve(int depth){
if(depth==k){
printf("%s\n",ans);
return;
}
for(int i=0;i<k;i++){
if(in[i]==0){
in[i]--;
ans[depth]=str[i];
for(int j=0;j<k;j++){
if(graph[i][j]) in[j]--;
}
solve(depth+1);
in[i]++;
for(int j=0;j<k;j++){
if(graph[i][j]) in[j]++;
}
}
}
}
int main()
{
int pp=0;
char s[1025];
while(gets(s)){
if(pp++) puts("");
k=0;
for(int i=0,len=strlen(s);i<len;i++){
if(isalpha(s[i]))
str[k++]=s[i];
}
sort(str,str+k);
for(int i=0;i<k;i++)
m[str[i]]=i;
memset(graph,0,sizeof(graph));
memset(in,0,sizeof(in));
gets(s);
int flag=0;
int x1,x2;
for(int i=0,len=strlen(s);i<len;i++){
if(isalpha(s[i])){
if(flag==0){
x1=m[s[i]];
flag=1;
}else{
x2=m[s[i]];
flag=0;
graph[x1][x2]=1;
in[x2]++;
}
}
}
memset(ans,0,sizeof(ans));
solve(0);
}
return 0;
}