题目描述 Description
有N个人,各自有一个姓名和ID(别名)。每个人的姓名和ID都没有重复。这些人依次进入一间房间,然后可能会离开。过程中可以得到一些信息,告知在房间里的某个人的ID。你的任务是准确地确定每个人的ID。
输入描述 Input Description
第一行是整数N,表示N个人,N<=20。
接下来的一行是N个人的ID,用一个空格分隔。
接下来的若干行是过程的记录:一个字母和一个字符串。字母是E、L或M中的一个。E表示进入房间,后面跟的字符串表示进来的人的姓名;L表示离开房间,后面跟的字符串表示离开的人的姓名;M表示回答询问,后面跟的字符串表示:当前用这个ID人在房间里面。
最后一行Q表示结束。
所有的姓名和ID都由不超过20个的小写字母组成。所有姓名都会在记录中出现。
一开始时,房间时空的。
输出描述 Output Description
共N行,每行形如:“姓名:ID”,如果ID不能确定,输出???。
按照姓名的字典顺序输出。
样例输入 Sample Input
7
bigman mangler sinbad fatman bigcheese frenchie capodicapo
E mugsy
E knuckles
M bigman
M mangler
L mugsy
E clyde
E bonnie
M bigman
M fatman
M frenchie
L clyde
M fatman
E ugati
M sinbad
E moriarty
E booth
Q
样例输出 Sample Output
bonnie:fatman
booth:???
clyde:frenchie
knuckles:bigman
moriarty:???
mugsy:mangler
ugati:sinbad
/* 匈牙利算法+map预处理,WA 80分,目前还没找出错误来 */ #include<cstdio> #include<iostream> #include<map> #include<cstring> #include<algorithm> #define M 30 using namespace std; map<string,int> id; map<string,int> mz; int in_mz[M],n,cnt; int used[M],belong[M],a[M][M],be2[M]; string idd[M],mzz[M]; struct node { int ID,MZ; };node ans[M]; bool find(int i) { for(int j=1;j<=n;j++)//循环姓名 if(!used[j]&&a[i][j]) { used[j]=1; if(!belong[j]||find(belong[j])) { belong[j]=i; return true; } } return false; } bool cmp(const node&x,const node&y) { return mzz[x.MZ]<mzz[y.MZ]; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) a[i][j]=1; for(int i=1;i<=n;i++) { string s;cin>>s; id[s]=i; idd[i]=s; } while(1) { char c;cin>>c; if(c=='Q')break; if(c=='E') { string s;cin>>s; if(!mz[s]) { mz[s]=++cnt; mzz[cnt]=s; } in_mz[mz[s]]=1; } if(c=='L') { string s;cin>>s; in_mz[mz[s]]=0; } if(c=='M') { string s;cin>>s;int num=id[s]; for(int i=1;i<=n;i++) if(!in_mz[i])a[num][i]=0; } } for(int i=1;i<=n;i++)//循环ID if(find(i)) memset(used,0,sizeof(used)); for(int i=1;i<=n;i++)be2[belong[i]]=i; for(int i=1;i<=n;i++)//循环ID { memset(used,0,sizeof(used)); a[i][be2[i]]=0; belong[be2[i]]=0; if(!find(i)) ans[i].MZ=be2[i],ans[i].ID=i; else ans[i].MZ=be2[i],ans[i].ID=0; a[i][be2[i]]=1; belong[be2[i]]=i; } sort(ans+1,ans+n+1,cmp); idd[0]="???"; for(int i=1;i<=n;i++) cout<<mzz[ans[i].MZ]<<":"<<idd[ans[i].ID]<<endl; return 0; }