您的位置:首页 > 其它

POJ1469(匈牙利算法求二分图最大匹配)

2017-09-21 18:08 405 查看
COURSES

Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 24326 Accepted: 9484
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 possible to form a committee of exactly P students that satisfies simultaneously the conditions: 

every student in the committee represents a different course (a student can represent a course if he/she visits that course) 

each course has a representative in the committee 

Input

Your program should read sets of data from the std input. The first line of the input contains the number of the data sets. Each data set is presented in the following format: 

P N 

Count1 Student1 1 Student1 2 ... Student1 Count1 

Count2 Student2 1 Student2 2 ... Student2 Count2 

... 

CountP StudentP 1 StudentP 2 ... StudentP CountP 

The first line in each data set contains two positive integers separated by one blank: P (1 <= P <= 100) - the number of courses and N (1 <= N <= 300) - the number of students. The next P lines describe in sequence of the courses �from course 1 to course P,
each line describing a course. The description of course i is a line that starts with an integer Count i (0 <= Count i <= N) representing the number of students visiting course i. Next, after a blank, you抣l find the Count i students, visiting the course, each
two consecutive separated by one blank. Students are numbered with the positive integers from 1 to N. 

There are no blank lines between consecutive sets of data. Input data are correct. 

Output

The result of the program is on the standard output. For each input data set the program prints on a single line "YES" if it is possible to form a committee and "NO" otherwise. There should not be any leading blanks at the start of the line.
Sample Input
2
3 3
3 1 2 3
2 1 2
1 1
3 3
2 1 3
2 1 3
1 1

Sample Output
YES
NO

Source
Southeastern Europe 2000

解题思路:直接求这个二分图的最大匹配数是否等于p就行。

最近刚学匈牙利算法,下面说一下我对这个算法的理解,以及一些二分图的一些简单性质。
首先说一些什么叫做二分图,那些繁琐的定义就不需要说了,简单一点,就一句话,如果图G的所有边的两个端点可以分为两个不相交的集合,这个图就是二分图。
那么你肯定想知道, 给你任意一个图,怎样判断这个图是不是二分图。
这个问题也很简单,一个图是二分图的充要条件是这个图中没有大于等于3的奇圈(环的长度),这个用代码判断也很简单,用并查集搞一下就行。
下面说一下匹配的概念,所谓匹配,说白了就是一个边集,这个边集中没有两条边有公共的端点,这个边集就就可以叫做一个匹配。边集里面边的数量就做这个匹配的匹配数。 而二分图的最大匹配数,就是让你找一个匹配,使这个匹配的匹配数最大。
下面介绍另外一些跟二分图有关的概念。
最大独立集(点):在N个点的图G中选出m个点,使这m个点两两之间没有边,求m最大值。
很显然最大独立集的大小为 n - 最大匹配数(如果这个图是一个二分图,n为这个图顶点的数量)
最小路径覆盖:用尽量少的不相交简单路径覆盖有向无环图G的所有结点。解决此类问题可以建立一个二分图模型。把所有顶点i拆成两个:X结点集中的i和Y结点集中的i',如果有边i->j,则在二分图中引入边i->j',设二分图最大匹配为m,则结果就是n-m。
最小点覆盖:找出数量最少的点,使得所有的边的至少一个端点在这个集合里,显然最小点覆盖的大小为最大匹配数

从上面的一些概念中我们可以知道,很多问题可以转化为求二分图的最大匹配问题。那么求一个二分图的最大匹配数就显得尤为重要了。
而匈牙利算法就是求解二分图最大匹配的一个算法。在介绍这个算法之前,先讲一下什么叫做增广路径。
一条增广路径是相对于一个匹配来说的,假设现在有一个匹配,如果一条路径满足:
1.这条路径上的第一个点和最后一个点都是未匹配点(这个点相连的边不是匹配中的边)。
2.匹配边和未匹配边交替出现,且第一条边和最后一条边为为匹配边。
那么我们称这条路径为这个匹配的一条增广路径,很显然,增广路径一定有奇数条边,并且匹配边的数量为偶数,未匹配边的数量为奇数,未匹配边数量刚好比匹配边数量多1.
由上面的增广路径定义可知,如果我们能够找到一个匹配的一条增广路径,那么我们可以用这条增广路径中的为未匹配边代替匹配边(也就是把这条增广路径中的匹配边删掉),把这些未匹配边当成一个新的匹配,那么当前匹配数量就相对于前面的匹配数量增加了1,所以匈牙利算法求解最大匹配的原理,就是一直找当前匹配的增广路径,直到找不到增广路径为止,这时的匹配就是最大匹配了。
下面是匈牙利算法的代码实现(基于dfs):
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 105;
int p, n;
int ans;
bool visit[3 * maxn];
int Match[3 * maxn];
vector<int> g[maxn];
void init()
{
ans = 0;
for(int i = 1; i <= p; i++)
{
g[i].clear();
}
memset(Match, -1, sizeof(Match));
}
bool dfs(int u)
{
for(int i = 0; i < g[u].size(); i++)
{
int v = g[u][i];
if(visit[v]) continue;
if(Match[v] == -1)
{
Match[v] = u;
return true;
}
visit[v] = true;
if(dfs(Match[v]))
{
Match[v] = u;
return true;
}
}
return false;
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &p, &n);
init();
for(int i = 1; i <= p; i++)
{
int num;
scanf("%d", &num);
for(int j = 1; j <= num; j++)
{
int v;
scanf("%d", &v);
g[i].push_back(v);
}
}
for(int i = 1; i <= p; i++)
{
memset(visit, false, sizeof(visit));
if(dfs(i)) ans++;
}
if(ans == p) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: