思路:枚举每个位置的最小字符,用最大匹配判断是否可行
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> #define Maxn 1010 using namespace std; int match[Maxn],vi[Maxn],num[Maxn],g[Maxn][Maxn],f[Maxn],ch[Maxn],n,le; void init() { memset(match,-1,sizeof(match)); memset(vi,0,sizeof(vi)); memset(num,0,sizeof(num)); memset(g,0,sizeof(g)); memset(f,0,sizeof(f)); memset(ch,0,sizeof(ch)); } int dfs(int u) { int i; for(i=1;i<=n;i++) if(!f[i]&&!vi[i]&&g[u][i]){ vi[i]=1; if(match[i]==-1||dfs(match[i])){ match[i]=u; return 1; } } return 0; } int OK() { int i,ans=0; memset(match,-1,sizeof(match)); for(i=1;i<=n;i++){ if(ch[i]) continue; memset(vi,0,sizeof(vi)); if(dfs(i)) ans++; } return ans==le; } int main() { int i,j,t,l,k; char str[Maxn],s[Maxn]; scanf("%d",&t); while(t--){ init(); scanf("%s",str+1); n=strlen(str+1); sort(str+1,str+1+n); for(i=1;i<=n;i++){ scanf("%s",s); l=strlen(s); for(j=1;j<=n;j++){ for(k=0;k<l;k++){ if(str[j]==s[k]){ g[i][j]=1; //cout<<i<<" "<<j<<endl; } } } } int ans=0; for(i=1;i<=n;i++){ memset(vi,0,sizeof(vi)); if(dfs(i)) ans++; } if(ans<n){ printf("NO SOLUTION "); continue; } memset(match,-1,sizeof(match)); le=n; for(i=1;i<=n;i++){ for(j=1;j<=n;j++)if(!f[j]&&g[i][j]){ ch[i]=j; f[j]=1; le--; if(OK()) break; le++; f[j]=0; } } for(i=1;i<=n;i++) printf("%c",str[ch[i]]); puts(""); } return 0; }