您的位置:首页 > 其它

UVALive 6322 最大匹配

2013-10-12 17:27 399 查看
思路:枚举每个位置的最小字符,用最大匹配判断是否可行

#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\n");
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: