二分图匹配技巧&模版

版权声明:希望能帮到弱校的ACMer成长,因为自己是弱校菜鸡~~~~ https://blog.csdn.net/Mr__Charles/article/details/82629187

技巧:

二分图的最小顶点覆盖:

    在二分图中求最少的边,让每条边至少和其中的一个点关联

    最小顶点覆盖=最大匹配数

DAG图(无回路有向图(Directed Acyclic Graph))的最小路径覆盖:

    用尽量少的不想交的简单路径覆盖图中的所有顶点

    最小路径覆盖=顶点数-最大匹配数

无向图的最小路径覆盖:

    无向二分图的最下路径覆盖=顶点数-最大二分匹配/2

  (因为无向图就是双向的一条边等于两次入图正向和反向,最后得到的匹配数多了一倍所以要除以2才是原本的匹配数)

点可以重复走的最小路径覆盖:

【题意】:派机器人去火星寻宝,给出一个无环的有向图,机器人可以降落在任何一个点上,再沿着路去其他点探索,我们的任务是计算至少派多少机器人就可以访问到所有的点。有的点可以重复去。

【思路】:我们仍可将问题转换为最小路径覆盖。如果一个人需要经过另一个人走过的点时候,让他直接从该点上空飞过去,越过该点,直接走下一个点。如果我们赋予每个人这种能力,那么求得的无重复点的最小路径覆盖结果,就是题目要求的结果,因为需要重复的地方只要飞过去,就可以不重复了。赋予这个能力的方法就是吧所有点能间接到达的点全都改为直接到达。

二分图的最大独立集:

    在二分图中任意两点都不相邻的顶点的最大集合

    最大独立集=结点数-最大匹配数

二部图的多重匹配

    一般的二部图只能匹配一个点,在多重匹配中,一个点可以匹配多给点

匈牙利算法模版:

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int MAXN = 505;
int k,n,m,g[MAXN];
bool line[MAXN][MAXN],used[MAXN];  //注意有向图和无向图line数组的空间大小
 
bool find(int x){
	for(int i = 1; i <= m; ++i){
		if(line[x][i] && !used[i]){//如果有暧昧并且还没有标记过
			used[i] = true;
			if(g[i] == 0 || find(g[i])){//名花无主或者能腾出个位置来,递归思想 
				g[i] = x;
				return true;
			}
		}
	}
	return false;
}
 
 
int match(){
	int sum = 0;
	for(int i = 1; i <= n ;++i){
		memset(used,false,sizeof(used)); //每次更新,以确保二分图的最大匹配 
		if(find(i)) 
		    sum++;
	}
	return sum;
}

猜你喜欢

转载自blog.csdn.net/Mr__Charles/article/details/82629187
今日推荐