二分图匹配 最大匹配数+最大点覆盖 POJ 1469+POJ 3041

最大匹配数就等于最大点覆盖,因为在图里面,凡是要覆盖的点必定是连通的,而最大匹配之后,若还有点没有覆盖到,则必定有新的匹配,与最大匹配数矛盾,如果去掉一些匹配,则必定有点没有覆盖到。

POJ 1469

比较简单,用的经典的二分图匹配算法。

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

#include <iostream>

#include <cstdio>

#include <cstring>

#include <algorithm>

using
namespace std;

int p[500][510],c[500][510];

int vis[510];

int lefts[510];

int cp[500],cc[500],n,m;

void
init()

{

    memset(vis,0,sizeof
vis);

    memset(lefts,-1,sizeof
lefts);

    memset(cp,0,sizeof
cp);

    memset(cc,0,sizeof
cc);

    memset(p,0,sizeof
p);

    memset(c,0,sizeof
c);

}

bool
match(int
u)

{

    for
(int
j=0;j<cp[u];j++){

        int
v=p[u][j];

        if
(1){

            vis[v]=1;

            if
(lefts[v]==-1 || match(lefts[v])){

                lefts[v]=u;

                return
true;

            }

        }

    }

    return
false;

}

int
main()

{

    int
t;

    scanf("%d",&t);

    while
(t--)

    {

        init();

        scanf("%d%d",&n,&m);

        for
(int
i=1;i<=n;i++){

            int
tmp,t2;

            scanf("%d",&tmp);

            for
(int
j=0;j<tmp;j++){

                scanf("%d",&t2);

                p[t2][cp[t2]++]=i;

                c[i][cc[i]++]=t2;

            }

        }

        int
ans=0;

        for
(int
i=1;i<=m;i++){

            memset(vis,0,sizeof
vis);

            if
(match(i)) ans++;

        }

        //cout<<ans<<endl;

        if
(ans==n) puts("YES");

        else 
puts("NO");

    }

    return
0;

}

  

POJ 3041

最小覆盖问题,转化为求最大匹配


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int mat[510][510],cnt[510];
int vis[510],lefts[510];
int n,k;
bool match(int u)
{
for (int i=0;i<cnt[u];i++){
int v=mat[u][i];
if (!vis[v]){
vis[v]=1;
if (lefts[v]==-1 || match(lefts[v])){
lefts[v]=u;
return true;
}
}
}
return false;
}
int main()
{

while (scanf("%d%d",&n,&k)!=EOF)
{
memset(mat,0,sizeof mat);
memset(cnt,0,sizeof cnt);
int a,b;
for (int i=0;i<k;i++){
scanf("%d%d",&a,&b);
mat[a][cnt[a]++]=b;
}
memset(lefts,-1,sizeof lefts);
int ans=0;
for (int i=1;i<=n;i++){
memset(vis,0,sizeof vis);
if (match(i)) ans++;
}
printf("%d\n",ans);
}
return 0;
}

二分图匹配 最大匹配数+最大点覆盖 POJ 1469+POJ 3041,布布扣,bubuko.com

时间: 2024-08-05 15:19:38

二分图匹配 最大匹配数+最大点覆盖 POJ 1469+POJ 3041的相关文章

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

匈牙利算法求二分图的最大匹配数

给定一个二分图,其中左半部包含n1n1个点(编号1~n1n1),右半部包含n2n2个点(编号1~n2n2),二分图共包含m条边. 数据保证任意一条边的两个端点都不可能在同一部分中. 请你求出二分图的最大匹配数. 二分图的匹配:给定一个二分图G,在G的一个子图M中,M的边集{E}中的任意两条边都不依附于同一个顶点,则称M是一个匹配. 二分图的最大匹配:所有匹配中包含边数最多的一组匹配被称为二分图的最大匹配,其边数即为最大匹配数. 输入格式 第一行包含三个整数 n1n1. n2n2 和 mm. 接下

UVALive 2523 Machine Schedule(二分图求最大匹配数)

题意:有两台机器,上面有多个工作区域,有多个任务,分别可以在两台机器的某一个区域上完成,两台机器一开始都在0区域上工作,每次更改区域,都会重新启动一次,让我们求出最小的重启次数. 思路:将两个区域连线,使用二分图,求出最大匹配数,容易想明白,正好就是最小重启的次数. 注意:0一开始就已经完成,不应该加入到匹配序列. 代码如下: #include<iostream> #include<algorithm> #include<queue> #include<cstdi

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 firs

POJ 1469 COURSES (二分图最大匹配 匈牙利算法)

COURSES Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18892   Accepted: 7455 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

poj3041-Asteroids , 二分图的最小顶点覆盖数 = 最大匹配数

点击打开链接 Konig定理:二分图的最小顶点覆盖数 = 二分图的最大匹配数 题意: 在N*N的网络中有K颗小行星.小行星i的位置是(Ri, Ci).如今有一个强力的武器可以用一发光束将一整行或一整列的小行星消灭.想要利用这个武器消灭全部的小行星最少须要几发光束? 分析: 以小行星的左右坐标建立二分图,就能够看出是求二分图的最小顶点覆盖数. #include <cstdio> #include <cstring> #include <vector> #include &

关于最大匹配,最小点覆盖,最少路径覆盖和最大独立集的总结

(1)二分图的最大匹配 匈牙利算法 (2)二分图的最小点覆盖 二分图的最小点覆盖=二分图的最大匹配 求最小点覆盖:从右边所有没有匹配过的点出发,按照增广路的“交替出现”的要求DFS.最终右边没有访问过的点和左边访问过的点组成最小点覆盖. 证明见这里 (3)二分图的最少边覆盖 二分图的最少边覆盖=点数-二分图的最大匹配 证明: 先贪心选一组最大匹配的边放进集合,对于剩下的没有匹配的点,随便选一条与之关联的边放进集合,那么得到的集合就是最小边覆盖. 所以有:最小边覆盖=最大匹配+点数-2*最大匹配=

HDU_1068_Girls and Boys_二分图匹配

Girls and Boys Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 10132    Accepted Submission(s): 4660 Problem Description the second year of the university somebody started a study on the roman

二分图的最大匹配:匈牙利算法

1. 二分图的匹配问题 1.1 二分图 简单来说,如果图中点可以被分为两组,并且使得所有边都跨越组的边界,则这就是一个二分图. 准确地说:把一个图的顶点划分为两个不相交集 U 和 V ,使得每一条边都分别连接U . V 中的顶点.如果存在这样的划分,则此图为一个二分图. 二分图的一个等价定义是:不含有「含奇数条边的环」的图.图 1 是一个二分图.为了清晰,我们以后都把它画成图 2 的形式. 1.2 匹配 在图论中,一个「匹配」(matching)是一个边的集合,其中任意两条边都没有公共顶点.例如