codevs 1027 姓名与ID

时间:2023-03-09 09:58:39
codevs 1027 姓名与ID
/*
二分图匹配 建图稍麻烦点
不过 有STL大法带我上天
说正经的 先假设都有关系 然后把确定的没有关系的删掉
这样跑出来的一定是完美匹配
至于确定的匹配嘛 删掉这一条 不再是完美匹配
然后记下排序输出
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#define maxn 25
using namespace std;
int n,sum,k,g[maxn][maxn],ans,match[maxn],use[maxn];
bool vis[maxn];
string s,q[maxn],id[maxn];
char si;
map<string,int>p,f,us;
struct node
{
int name,ID;
}a[maxn];
int cmp(node x,node y)
{
return q[x.name]<q[y.name];
}
bool Dfs(int s)
{
for(int i=;i<=n;i++)
if(vis[i]==&&g[s][i])
{
vis[i]=;
if(match[i]==||Dfs(match[i]))
{
match[i]=s;
return ;
}
}
return ;
}
int main()
{
cin>>n;
for(int i=;i<=n;i++)
{
cin>>s;p[s]=i;id[i]=s;
}
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
g[i][j]=;
while()
{
cin>>si;
if(si=='Q')break;
cin>>s;
if(si=='E')
{
if(us[s]==)q[++k]=s;
f[s]=;us[s]=;
}
if(si=='L')f[s]=;
if(si=='M')
{
for(int i=;i<=n;i++)
if(f[q[i]]==)
g[i][p[s]]=;
}
}
for(int i=;i<=n;i++)
{
memset(vis,,sizeof(vis));
ans+=Dfs(i);
}
int Tar=ans;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
if(!g[i][j])continue;
g[i][j]=;ans=;
memset(match,,sizeof(match));
for(int o=;o<=n;o++)
{
memset(vis,,sizeof(vis));
ans+=Dfs(o);
}
if(ans<Tar)
{
a[++sum].name=i;
a[sum].ID=j;
use[i]=;
}
g[i][j]=;
}
for(int i=;i<=n;i++)
if(use[i]==)a[++sum].name=i;
sort(a+,a++sum,cmp);
for(int i=;i<=sum;i++)
if(use[a[i].name])cout<<q[a[i].name]<<":"<<id[a[i].ID]<<endl;
else cout<<q[a[i].name]<<":???"<<endl;
return ;
}