求最大匹配后,判断每个人是否可以有别的匹配,沿原匹配走出回路则有。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<set>
using namespace std;
int n;
int line[30][30];
int b[30],g[30];
bool used[30];
map<string,int>name;
string na[30];
map<string,int>id;
string di[30];
set<int>se;
set<int>leave;
bool vis[30];
struct Node
{
string name,id;
bool operator<(const Node& u)const
{
return name<u.name;
}
};
Node p[30];
int e=0;
bool find(int x);
bool check(int x);
int main()
{
memset(b,0,sizeof(b));
memset(g,0,sizeof(g));
string str;
char ch[2];
scanf("%d",&n);
for(int i=0;i<n;i++){
cin>>str;
id[str]=i+1;
di[i+1]=str;
leave.insert(i+1);
}
int o=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
line[i][j]=1;
}
while(~scanf("%s",ch)){
if(ch[0]=='Q')
break;
cin>>str;
if(ch[0]=='E'){
if(name[str]==0){
name[str]=o++;
na[o-1]=str;
}
se.insert(name[str]);
leave.erase(name[str]);
}
else if(ch[0]=='L'){
leave.insert(name[str]);
se.erase(name[str]);
}
else{
int k=id[str];
for(set<int>::iterator it=leave.begin();it!=leave.end();it++){
line[*it][k]=0;
}
}
}
for(int i=1;i<=n;i++){
memset(used,0,sizeof(used));
find(i);
}
for(int i=1;i<=n;i++){
memset(vis,0,sizeof(vis));
memset(used,0,sizeof(used));
if(check(i)){
p[e].name=na[i];
p[e++].id="???";
}
else{
p[e].name=na[i];
p[e].id=di[b[i]];
e++;
}
}
sort(p,p+e);
for(int i=0;i<e;i++)
cout<<p[i].name<<":"<<p[i].id<<endl;
return 0;
}
bool find(int x)
{
for(int i=1;i<=n;i++){
if(line[x][i]==1&&used[i]==0){
used[i]=1;
if(g[i]==0||find(g[i])){
b[x]=i;
g[i]=x;
return true;
}
}
}
return false;
}
//判断x能不能有别的匹配
bool check(int x)
{
if(vis[x]==1)//走出回路
return true;
vis[x]=1;
for(int i=1;i<=n;i++){
if(used[i]==0&&line[x][i]&&g[i]!=x){//不是原匹配
used[i]=1;
if(g[i]==0||check(g[i]))
return true;
}
}
return false;
}