二分图简单概念&&HDU 2063

二分图:

二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。

简单的说,一个图被分成了两部分,相同的部分没有边,那这个图就是二分图,二分图是特殊的图。

匹配:

给定一个二分图G,在G的一个子图M中,M的边集{E}中的任意两条边都不依附于同一个顶点,则称M是一个匹配。

极大匹配(Maximal Matching)是指在当前已完成的匹配下,无法再通过增加未完成匹配的边的方式来增加匹配的边数。最大匹配(maximum matching)是所有极大匹配当中边数最大的一个匹配。选择这样的边数最大的子集称为图的最大匹配问题。

如果一个匹配中,图中的每个顶点都和图中某条边相关联,则称此匹配为完全匹配,也称作完备匹配。

求二分图匹配可以用最大流(Maximal Flow)或者匈牙利算法(Hungarian Algorithm)

注意匈牙利算法,除了二分图多重匹配外在二分图匹配中都可以使用。

例题:HDU 2063

过山车

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 23222    Accepted Submission(s): 10059

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

二分匹配模板题

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <cstdlib>
#include <iomanip>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
using namespace std;
#define lowbit(x) (x&(-x))
#define max(x,y) (x>y?x:y)
#define min(x,y) (x<y?x:y)
#define MAX 100000000000000000
#define MOD 1000000007
#define pi acos(-1.0)
#define ei exp(1)
#define PI 3.141592653589793238462
#define ios() ios::sync_with_stdio(false)
#define INF 0x3f3f3f3f
#define mem(a) (memset(a,0,sizeof(a)))
typedef long long ll;
int k,m,n,vis[550],x,y;
int g[550][550],pos[550];
bool find(int x)
{
    for(int i=1;i<=n;i++)
    {
        if(g[x][i]&&!vis[i])//有机会并且这个男生没有被标记
        {
            vis[i]=1;
            if((pos[i]==0)/*这个男生还没有女生选*/|| find(pos[i])/*或者给已选了这个男生的女生从新在找一个男同伴*/)
            {
                pos[i]=x;
                return true;//能找到,返回真;
            }
        }
    }
    return false;
}
int main()
{
    while(scanf("%d",&k)&&k)
    {
        scanf("%d %d",&m,&n);
        memset(g,0,sizeof(g));
        memset(pos,0,sizeof(pos));
        for(int i=0;i<k;i++)
        {
            scanf("%d%d",&x,&y);
            g[x][y]=1;//女生x不反对和男生ycp
        }
        int sum=0;
        for(int i=1;i<=m;i++)
        {
            memset(vis,0,sizeof(vis));//女n号;
            if(find(i)) sum++;
        }
        printf("%d\n",sum);
    }
    return 0;
}
时间: 2024-10-09 18:21:17

二分图简单概念&&HDU 2063的相关文章

hdu 2063 过山车(二分图匹配最大匹配数模板)

过山车 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 10776    Accepted Submission(s): 4748 Problem Description RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了.可是,过山车的每一排只有两个座位,而且还有条不成文的规矩,就是每个女生必须找个个男生做par

HDU 2063 过山车 二分图题解

一个男女搭配的关系图,看可以凑成多少对,基本和最原始的一个二分图谜题一样了,就是 一个岛上可以凑成多少对夫妻的问题. 所以是典型的二分图问题. 使用匈牙利算法,写成两个函数,就非常清晰了. 本程序还带分配释放程序,当然oj一般不需要.但是好的程序一定要. #include <stdio.h> #include <stdlib.h> int K, M, N, a, b; int *linker; bool **gra, *used; void initGraph() { gra =

HDU 2063:过山车(二分匹配,匈牙利算法)

过山车 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9745    Accepted Submission(s): 4294 Problem Description RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了.可是,过山车的每一排只有两个座位,而且还有条不成文的规矩,就是每个女生必须找个个男生做par

凸包---(简单概念)

这里先介绍点概念(一般是点集覆盖问题)输入各个点的坐标 1. 将各点排序(必须的) ,为保证形成圈,把 P0 在次放在点表的尾 部: 2. 准备堆栈:建立堆栈 S,栈指针设为t,将0.1.2 三个点压入堆栈 S: 3. 对于下一个点 i 只要 S[t-1].S[t].i不做左转 就反复退栈: 将 i压入堆栈 S 4.堆栈中的点即为所求凸包: 其核心用 C 语言表示,仅仅是下面一段: t=-1; s[++t]=0; s[++t]=1; s[++t]=2; for (i=3;i<n;i++) { w

句柄的简单概念

1.  句柄概念 句柄是Windows程序中的概念,本质是一个4字节(64位程序中为8字节)整数值,用来标示不同实例. 由于数据在内存地址中是变动的,为管理内存,windows引入句柄概念. 2.  句柄与普通指针 指针包含的是引用对象的内存地址,而句柄则是由系统所管理的引用标识,该标识可以被系统重新定位到一个内存地址上. 3.  句柄的使用 一个句柄,只有确定了一个项目的时候,才开始有意义.句柄对应着项目表中的一项,只有WINDOWS本身才能直接存取这个表,应用程序只能通过API函数来处理不同

hdu 2063

过山车 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 10714    Accepted Submission(s): 4721 Problem Description RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了.可是,过山车的每一排只有两个座位,而且还有条不成文的规矩,就是每个女生必须找个个男生做par

[简单博弈] hdu 1525 Euclid&#39;s Game

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1525 Euclid's Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1832    Accepted Submission(s): 808 Problem Description Two players, Stan and

处理器boot的简单概念及误区

研一的时候在S3C6410的开发板上完成了一个简单的bootloader的设计,有一些想法可以顾及到其他处理器的设计上,在这里和大家分享一下. 晚一些的时候我再跟大家讲如何去设计 :) 首先什么叫做bootloader?在我看来,其实bootloader就是一个搬运工,负责将串行或并行flash中的数据搬运至sdram,再将pc指针切换至sdram的映射地址.大家也许会问,8/16位单片机或者CORTEX-M系列的处理器为啥不需要bootloader,在这里其实是有误区的,其实这些处理器也是有b

端口和协议的简单概念

1.端口的简单概念: 192.168.33.1代表一台主机,但是主机上可能会有很多服务, 一台主机上的不同服务功能,就是通过端口区分,然后让外部人员访问. 远程连接服务 ssh  22端口 2.协议的简单概念: 汉语.英语,不同的服务提供了不同的端口,对应了不同的功能,通信方式可能也是不同的,这种通信方式我们就可以理解为协议. 一台主机上的不同服务功能,就是通过端口区分,不同的服务端口,客户端和服务器之间通信,就可能使用不同的协议