POJ 1274&&HDU 2063 二分图匹配模板题

POJ 1274 The Perfect Stall

题目链接:http://poj.org/problem?id=1274

Description

Farmer John completed his new barn just last week, complete with all the latest milking technology. Unfortunately, due to engineering problems, all the stalls in the new barn are different. For the first week, Farmer John randomly assigned cows to stalls, but it quickly became clear that any given cow was only willing to produce milk in certain stalls. For the last week, Farmer John has been collecting data on which cows are willing to produce milk in which stalls. A stall may be only assigned to one cow, and, of course, a cow may be only assigned to one stall. 
Given the preferences of the cows, compute the maximum number of milk-producing assignments of cows to stalls that is possible. 

Input

The input includes several cases. For each case, the first line contains two integers, N (0 <= N <= 200) and M (0 <= M <= 200). N is the number of cows that Farmer John has and M is the number of stalls in the new barn. Each of the following N lines corresponds to a single cow. The first integer (Si) on the line is the number of stalls that the cow is willing to produce milk in (0 <= Si <= M). The subsequent Si integers on that line are the stalls in which that cow is willing to produce milk. The stall numbers will be integers in the range (1..M), and no stall will be listed twice for a given cow.

Output

For each case, output a single line with a single integer, the maximum number of milk-producing stall assignments that can be made.

Sample Input

5 5
2 2 5
3 2 3 4
2 1 5
3 1 2 5
1 2 

Sample Output

4

题意:

农夫约翰上周完成了他的新谷仓,配备了所有最新的挤奶技术。 不幸的是,由于工程问题,新酒吧的所有摊位都不同。 第一周,约翰随意将奶牛分配到摊位,但他很快就清楚地知道,任何给定的奶牛只能在某些摊位生产牛奶。 在过去的一周里,约翰一直在收集哪些奶牛将在其中生产牛奶的数据。 一个摊位可能只被分配到一个摊位。考虑到奶牛的喜好,计算可能的奶牛产奶量的最大数量。

扫描二维码关注公众号,回复: 2756256 查看本文章

分析:典型的二分图最大匹配,作为入门模板题熟悉知识点是可以的。

上代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN=1000;
int uN,vN;  //u,v数目
int g[MAXN][MAXN];//编号是0~n-1的,存图 
int linker[MAXN];//v集合中所匹配的u是哪个 
bool used[MAXN];//是否被搜索过 
bool dfs(int u)
{
    int v;
    for(v=0;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 hungary()
{
    int res=0;
    int u;
    memset(linker,-1,sizeof(linker));
    for(u=0;u<uN;u++)
    {
        memset(used,0,sizeof(used));
        if(dfs(u))  res++;
    } 
    return res;   
}     
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int num,v;
	while(~scanf("%d%d",&uN,&vN))
	{
		memset(g,0,sizeof(g));
		for(int i=1;i<=uN;i++)
		{
			scanf("%d",&num);
			while(num--)
			{
				scanf("%d",&v);
				g[i-1][v-1]=1;
			}
		}
		printf("%d\n",hungary());
	}
	return 0;
}

HDU 2063 过山车:

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2063

Problem Description

RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了。可是,过山车的每一排只有两个座位,而且还有条不成文的规矩,就是每个女生必须找个个男生做partner和她同坐。但是,每个女孩都有各自的想法,举个例子把,Rabbit只愿意和XHD或PQK做partner,Grass只愿意和linle或LL做partner,PrincessSnow愿意和水域浪子或伪酷儿做partner。考虑到经费问题,boss刘决定只让找到partner的人去坐过山车,其他的人,嘿嘿,就站在下面看着吧。聪明的Acmer,你可以帮忙算算最多有多少对组合可以坐上过山车吗?

Input

输入数据的第一行是三个整数K , M , N,分别表示可能的组合数目,女生的人数,男生的人数。0<K<=1000
1<=N 和M<=500.接下来的K行,每行有两个数,分别表示女生Ai愿意和男生Bj做partner。最后一个0结束输入。

Output

对于每组数据,输出一个整数,表示可以坐上过山车的最多组合数。

Sample Input

 

6 3 3 1 1 1 2 1 3 2 1 2 3 3 1 0

Sample Output

 

3

做这题的时候,理解出现了一些小错误,二分图中u集合和v集合的编号之间并不互相关联,即两个集合间序号是可以重复的,g[1][1]=1,是在u集合中序号为1的点和v集合中序号为1的点间加边。实际上,这就是一道模板题······

上代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN=1000;
int uN,vN;  //u,v数目,u为点,v为边 
int g[MAXN][MAXN];//编号是0~n-1的,存图 
int linker[MAXN];//v集合中所匹配的u是哪个 
bool used[MAXN];//是否被搜索过 
bool dfs(int u)
{
    int v;
    for(v=0;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 hungary()
{
    int res=0;
    int u;
    memset(linker,-1,sizeof(linker));
    for(u=0;u<uN;u++)
    {
        memset(used,0,sizeof(used));
        if(dfs(u))  res++;
    } 
    return res;   
}     
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int w,m;
	int u,v;
	while(~scanf("%d",&vN)&&vN)
	{
		scanf("%d%d",&w,&m);
		memset(g,0,sizeof(g));
		uN=w+m;
		for(int i=1;i<=vN;i++)
		{
			scanf("%d%d",&u,&v);
			g[u-1][v-1]=1;
		}
		printf("%d\n",hungary());
	}
	return 0;
}

模板地址:https://www.cnblogs.com/kuangbin/archive/2011/08/09/2132828.html

猜你喜欢

转载自blog.csdn.net/qq_41279172/article/details/81632839