[网络流] 二分图匹配

二分图匹配,本质上是最大流问题的一种特殊情况。

指派问题
有N台计算机和K个任务,我们可以给每台计算机分配一个任务,每台计算机能够处理的任务种类各不相同,请求出最多能够处理的任务个数。

这个问题可以像下面这样转化为图论模型来分析。我们可以像下面这样来定义无向二分图 G=(UV,E)

U是代表计算机的顶点集合,V是代表任务的顶点集合,对于任意uUvV 计算机u能够处理任务v(u,v)E

而G中满足两两不含公共端点的边集合ME 的基数M的最大值,就是我们所要求的最大的任务个数。

[网络流] 二分图匹配_第1张图片

图论术语中,我们将这种两两不含公共端点的边集合M称为匹配,而元素最多的M则成为最大匹配。而元素最多的M则成为最大匹配。当最大匹配的匹配数满足2|M| = V时,又称为完美匹配。特别地,二分图中的匹配又称为二分图匹配。向这道题一样,二分图匹配常常在指派问题的模型中出现,也常常在程序设计竞赛中登场。

可以将二分图最大匹配问题看成是最大流的一种特殊情况,对原图做如下变形:

将原图中的所有无相边 e 改为有向边,方向从UV,容量为1,增加源点 s 和汇点 t ,从s向所有的顶点uU连一条容量为1的边,从所有的顶点vVt 连一条容量为1的边。

这样变形得到的新图中最大S-T流的流量就是原二分图G中最大匹配的匹配数,而U-V之间流量为正的边集合就是最大匹配。该算法的复杂度为O(|V||E|)

//此处省略了部分建边、寻找增广路和求解最大流的代码
int N,K;
bool can[MAXN][MAXN];// can[i][j]:计算机i能够处理任务j
void solve()
{
    //0~N-1:计算机对应的顶点,
    //N~N-K+1:任务对应的顶点
    int s = N+K,t = s+1;
    //在源点和计算机之间连边
    for(int i = 0; i
    {
        add_edge(s, i, 1);
    }
    //在任务和汇点之间连边
    for(int i = 0;i
    {
        add_edge(N+i,t,1);
    }
    //在计算机和任务之间连边
    for(int i = 0; i < N; i++)
    {
        for(int j = 0; j < K; j++)
        {
            if (can[i][j])
            {
                add_edge(i,N+j,1);
            }
        }
    }
    printf("%d\n",max_flow(s,t));
}

你可能感兴趣的:(————ACM训练————,5,图论)