題意:給定n個人,每個人可能會兩種本事,寫代碼或者測數據,或者都會,還有他的排名,指定分組選擇兩個人分別會寫代碼和測數據且排名差距爲2,求組合數最大有多少
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int match[1005];
bool vis[1005];
struct Node{
char name[25];
int spec;
int rank;
}lvex[1005];
Node rvex[1005];
bool g[1005][1005];
int ln,rn;
bool dfs(int l){ //二分圖最大匹配
for(int i=1;i<=rn;i++){
if(g[l][i]&&!vis[i]){
vis[i]=1;
if(match[i]==-1||dfs(match[i])){ //找到增廣通路,更新ans+1的匹配邊(原來是ans條匹配邊)
match[i]=l;
return true;
}
}
}
return false; //沒找到增廣通路
}
int fit(){
int ans=0;
memset(match,-1,sizeof(match));
for(int i=1;i<=ln;i++){
memset(vis,0,sizeof(vis));
if(dfs(i)) ans++;
}
return ans;
}
int main()
{
int n;
char s1[100],s2[100];
int temp;
memset(g,0,sizeof(g));
scanf("%d",&n);
ln=rn=0;
for(int i=1;i<=n;i++)
{
scanf("%s %s %d",s1,s2,&temp);
if(temp%4>=2){ //通過%4分成左右兩個二分圖
strcpy(lvex[++ln].name,s1);
if(strcmp("statements",s2)==0) lvex[ln].spec=1;
else if(strcmp("testdata",s2)==0) lvex[ln].spec=2;
else lvex[ln].spec=3;
lvex[ln].rank=temp;
}
else{
strcpy(rvex[++rn].name,s1);
if(strcmp("statements",s2)==0) rvex[rn].spec=1;
else if(strcmp("testdata",s2)==0) rvex[rn].spec=2;
else rvex[rn].spec=3;
rvex[rn].rank=temp;
}
}
for(int i=1;i<=ln;i++)
{
for(int j=1;j<=rn;j++)
{
if((lvex[i].spec!=rvex[j].spec||rvex[j].spec==3||lvex[i].spec==3)&&(lvex[i].rank-rvex[j].rank==2||lvex[i].rank-rvex[j].rank==-2))
{
g[i][j]=1;
}
}
}
printf("%d\n",fit());
for(int i=1;i<=rn;i++)
{
if(match[i]!=-1)
{
if(lvex[match[i]].spec==1||(lvex[match[i]].spec==3&&rvex[i].spec==2))
printf("%s %s\n",lvex[match[i]].name,rvex[i].name);
else
printf("%s %s\n",rvex[i].name,lvex[match[i]].name);
}
}
}