hiho1122_二分图匈牙利算法

题目

给定一个图的N个节点和节点之间的M条边,数据保证该图可以构成一个二分图。求该二分图最大匹配。 
题目链接:二分图最大匹配 
    首先通过染色法,将图的N个节点分成两个部分;然后通过匈牙利算法求二分图的最大匹配。

实现

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<string>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<algorithm>
using namespace std;

struct Edge{
	int to;
	int next;
};
Edge gEdges[80005];
int gEdgeIndex;
int gHead[10005];
int gMatch[10005];
bool gVisited[10005];
int gColor[10005];
bool conflict;
void Init(){
	gEdgeIndex = 0;
	memset(gHead, -1, sizeof(gHead));
	memset(gVisited, false, sizeof(gVisited));
	memset(gMatch, -1, sizeof(gMatch));
	memset(gColor, -1, sizeof(gColor));
	conflict = false;
}
void InsertEdge(int u, int v){
	int e = gEdgeIndex++;
	gEdges[e].to = v;
	gEdges[e].next = gHead[u];
	gHead[u] = e;
}

void PaintColor(int node, int c){
	if (conflict)
		return;
	gColor[node] = c;
	for (int e = gHead[node]; e != -1; e = gEdges[e].next){
		int x = gEdges[e].to;
		if (gColor[x] == c){
			conflict = true;
			return;
		}
		if (gColor[x] == -1)
			PaintColor(x, 1 - c);
	}
}

bool Dfs(int node){
	for (int e = gHead[node]; e != -1; e = gEdges[e].next){
		int v = gEdges[e].to;
		if (!gVisited[v]){
			gVisited[v] = true; //置位
			if (gMatch[v] == -1){
			//如果对方的阵营中v点还没有匹配,则成功找到一条交错路径
				gMatch[node] = v;
				gMatch[v] = node;
				return true;
			}
			else if (Dfs(gMatch[v])){
			//如果对方阵营中v有匹配点,匹配点肯定在己方阵营,则继续从己方阵营的点
			//递归
				gMatch[node] = v;
				gMatch[v] = node;
				return true;
			}
		}
	}
	return false;
}
int main(){
	int n, m, u, v;
	Init();
	scanf("%d %d", &n, &m);

	for (int i = 0; i < m; i++){
		scanf("%d %d", &u, &v);
		InsertEdge(u, v);
		InsertEdge(v, u);
	}

	for (int i = 1; i <= n; i++)
		if (gColor[i] == -1)
			PaintColor(i, 0);

	int ans = 0;
	for (int i = 1; i <= n; i++){
		if (gColor[i] == 0 && gMatch[i] == -1){//从固定一方阵营中,不断找未匹配点
		//寻找交错路,找到一条交错路,则匹配个数增加1
			memset(gVisited, false, sizeof(gVisited));
			if (Dfs(i))
				ans++;
		}
	}
	printf("%d\n", ans);
	return 0;
}
时间: 2024-10-06 13:13:16

hiho1122_二分图匈牙利算法的相关文章

POJ 3020 Antenna Placement(二分图 匈牙利算法)

题目网址:  http://poj.org/problem?id=3020 题意: 用椭圆形去覆盖给出所有环(即图上的小圆点),有两种类型的椭圆形,左右朝向和上下朝向的,一个椭圆形最多可以覆盖相邻的两个小圆点.   思路: 将每个小圆点看作是一个顶点,因为一个椭圆只能覆盖两个小圆点,我们就可以把这个图看成一个二分图.将相邻的两个点,一个看作是X集合内顶点,另一个看成是Y集合内顶点.但要注意的是一个顶点可能不止和一个顶点想连(如上图情况),所以我们要把上述情况看作是一个无向图,而不是有向图.无向图

二分图 匈牙利算法

匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名.匈牙利算法是基于Hall定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法. -------等等,看得头大?那么请看下面的版本: 通过数代人的努力,你终于赶上了剩男剩女的大潮,假设你是一位光荣的新世纪媒人,在你的手上有N个剩男,M个剩女,每个人都可能对多名异性有好感(-_-||暂时不考虑特殊的性取向),如果一对男女互有好感,那么你就可以把这一对撮合在一起,现在

二分图&amp;&amp;匈牙利算法(二分图基本算法)

二分图 二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图. 区别二分图,关键是看点集是否能分成两个独立的点集.如下图所示 二分图的最大匹配 给定一个二分图G,在G的一个子图M中,M的边集中的任意两条边都不依附于同一个顶点,则称M是一个匹配. 选择这样的边数最大的子集称为图的最大匹配问题(maxim

POJ 3041 Asteroids(二分图 &amp;&amp; 匈牙利算法 &amp;&amp; 最小点覆盖)

嗯... 题目链接:http://poj.org/problem?id=3041 这道题的思想比较奇特: 把x坐标.y坐标分别看成是二分图两边的点,如果(x,y)上有行星,则将(x,y)之间连一条边,而我们要做的就是要找尽量少的点把所有的边覆盖,即为最小点覆盖问题,根据König定理:最小覆盖点数=最大匹配数,所以就可以用匈牙利算法求最大匹配了. AC代码: 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream&

二分图匈牙利算法

求二分图的算法——匈牙利 例题: https://www.luogu.org/problem/P3386 思路: 首先二分图是一个求一堆东西(例如狗),喜欢一些东西(例如肉),但是他们喜欢的肉不同,求最大限度能满足多少条狗的问题.那么我们可以画一个图,把狗放在一侧,把肉放在一侧. 如果第i只狗, 喜欢第j个肉,那么,就从i-->j连一条有向边. 然后, 我们用贪心的思想进行dfs. 我们定义choose[i]表示第i个肉被第choose[i]个狗获得. 然后我们定义一个vis数组,防止死循环. 

POJ - 1469 COURSES [二分图匈牙利算法]

COURSES Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 24919   Accepted: 9679 Description Consider a group of N students and P courses. Each student visits zero, one or more than one courses. Your task is to determine whether it is poss

二分图匈牙利算法模板

最大匹配数:最大匹配的匹配边的数目 最小点覆盖数:选取最少的点,使任意一条边至少有一个端点被选择 最大独立数:选取最多的点,使任意所选两点均不相连 最小路径覆盖数:对于一个 DAG(有向无环图),选取最少条路径,使得每个顶点属于且仅属于一条路径.路径长可以为0(即单个点). 定理1:最大匹配数 = 最小点覆盖数(这是 Konig 定理) 定理2:最大匹配数 = 最大独立数 定理3:最小路径覆盖数 = 顶点数 - 最大匹配数 const int N=555;///两边的最大数量 bool tu[N

POJ 1325 二分图匹配/匈牙利算法

Machine Schedule Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 11922 Accepted: 5077 Description As we all know, machine scheduling is a very classical problem in computer science and has been studied for a very long history. Scheduling p

匈牙利算法dfs模板 [二分图][二分图最大匹配]

最近学了二分图最大匹配,bfs模板却死活打不出来?我可能学了假的bfs 于是用到了dfs模板 寻找二分图最大匹配的算法是匈牙利算法 匈牙利算法的主要程序是寻找增广路 寻找增光路是过程是:从一个未经配对的点出发,历经未配边.匹配边.未配边.匹配边.未配边....最终到达一个未配点的过程,只要把路径中的未配边和匹配边的“身份”对调,匹配就加一了.这就是一个寻找增广路的过程,通过不断寻找增广路,可以找到最大的匹配. 1 #include<cstdio> 2 #include<cstring&g