UVALive5874 - Social Holidaying-二分图匹配/匈牙利算法

有n个家庭,m个房间,一个房间只能两个家庭住。求最大匹配。

比较标准的二分图问题。先初始化把可能的家庭建边,然后跑一边匈牙利算法。

最后的答案是最大匹配数/2,因为建图时有重复。

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>

using namespace std;

const int MAXN = 410;
int uN,vN;
int g[MAXN][MAXN];
int linker[MAXN];
bool used[MAXN];

int dfs(int u)
{
    for(int v=1;v<=vN;v++) if(g[u][v] && !used[v])
    {
        used[v] = true;
        if(linker[v] == -1 || dfs(linker[v]))
        {
            linker[v] = u;
            return true;
        }
    }
    return false;
}

int Hungarian()
{
    int res = 0;
    memset(linker,-1,sizeof linker);
    for(int u=1;u<=uN;u++)
    {
        memset(used,false,sizeof used);
        if(dfs(u)) res++;
    }
    return res;
}

int T,n,m;
int R[500];

map<int,int> B;

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        B.clear();
        memset(g,0,sizeof g);

        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&R[i]);
        }
        for(int i=0;i<m;i++)
        {
            int tmp=0;
            scanf("%d",&tmp);
            B[tmp] = 1;
        }

        uN = n;vN = n;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(i == j) continue;
                if(B[R[i]+R[j]] == 1)
                {
                    g[i][j]=g[j][i]=1;
                }
            }
        }

        printf("%d\n",Hungarian()/2);
    }
}

 

你可能感兴趣的:(UVALive5874 - Social Holidaying-二分图匹配/匈牙利算法)