Two Sides of the Same Coin --二分圖的最大匹配

題意:給定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);
        }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章