题意:给出一串字母和关系,问输出所有可能满足拓扑排序的排列组合
思路:由于要输出所有的组合并且题目保证一定有输出,那么可以用dfs来构造组合。需要满足两个条件
1.当前被选的字母必须有效(即mark[i]==true)且当前被选的字母vis=false(即还没被选)。
2.当我们从前到后依次选择一个字母x放进topo数组的时候,我们要保证在topo数组的当前位置cnt的前面那些位置中不会出现y这种字母。其中y<x,即y被要求出现在x后面。
#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <set>
#include <ctime>
#include <cmath>
#include <cctype>
using namespace std;
#define maxn 30
#define LL long long
int cas=1,T;
int G[maxn][maxn];
int vis[maxn];
int ans[maxn];
int n,cnt;
int mark[maxn];
bool ok(int i,int cnt)
{
for (int j = 0;j<cnt;j++)
if (G[i][ans[j]])
return false;
return true;
}
void dfs(int cnt)
{
if (cnt==n)
{
for (int i = 0;i<n;i++)
printf("%c",ans[i]+'a');
printf("\n");
}
else
{
for (int i = 0;i<26;i++)
if (mark[i] && !vis[i] && ok(i,cnt))
{
vis[i]=1;
ans[cnt]=i;
dfs(cnt+1);
vis[i]=0;
}
}
}
int main()
{
char str[1000];
while (gets(str))
{
n=0;
memset(mark,0,sizeof(mark));
memset(G,0,sizeof(G));
memset(vis,0,sizeof(vis));
for (int i = 0;str[i];i++)
if(str[i]!=' ')
{ mark[str[i]-'a']=1;
n++;
}
gets(str);
for (int i = 0;str[i];i++)
if (str[i]!=' ')
{
int a,b;
a=str[i++]-'a';
while (str[i]==' ')
i++;
b=str[i]-'a';
G[a][b]=1;
}
dfs(0);
printf("\n");
}
//freopen("in","r",stdin);
//scanf("%d",&T);
//printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
return 0;
}