四川第七届 D Vertex Cover(二分图最小点覆盖,二分匹配模板)

Vertex Cover

frog has a graph with nn vertices v(1),v(2),…,v(n)v(1),v(2),…,v(n) and mm edges (v(a1),v(b1)),(v(a2),v(b2)),…,(v(am),v(bm))(v(a1),v(b1)),(v(a2),v(b2)),…,(v(am),v(bm)).

She would like to color some vertices so that each edge has at least one colored vertex.

Find the minimum number of colored vertices.

Input

The input consists of multiple tests. For each test:

The first line contains 22 integers n,mn,m (2≤n≤500,1≤m≤n(n?1)22≤n≤500,1≤m≤n(n?1)2). Each of the following mm lines contains 22 integers ai,biai,bi (1≤ai,bi≤n,ai≠bi,min{ai,bi}≤301≤ai,bi≤n,ai≠bi,min{ai,bi}≤30)

Output

For each test, write 11 integer which denotes the minimum number of colored vertices.

Sample Input

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

Sample Output

    1
    2

题意:有n个点m条边,每条边至少有一个顶点染色,至少要染多少个点

思路:二分图最小点覆盖,有一个公式 二分图最大匹配=最小点覆盖,匈牙利算法一代就出来了

#include<cstdio>
#include<string.h>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<deque>
using namespace std;
#define ll unsigned long long
vector<int>v[505];
int match[505];
bool used[505];
bool dfs(int x)
{
    used[x]=1;//标记询问过了
    for(int i=0;i<v[x].size();i++)
    {
        int y=v[x][i];
        int w=match[y];
        if(w<0||!used[w]&&dfs(w))
        {//如果它没有匹配过或者(没有问过而且可以找到其它)
            match[x]=y;
            match[y]=x;
            return 1;
        }
    }
    return 0;
}
int main()
{
    int n,m;
    while(cin>>n>>m)
    {
        for(int i=0;i<=502;i++) v[i].clear();
        for(int i=1;i<=m;i++)
        {
            int x,y;
            cin>>x>>y;
            v[x].push_back(y);
            v[y].push_back(x);
        }
        int res=0;
        memset(match,-1,sizeof(match));
        for(int i=1;i<=n;i++)
        {
            if(match[i]<0)//还没匹配
            {
                memset(used,0,sizeof(used));//每次都要初始化
                if(dfs(i))
                //如果能匹配
                    res++;
                }
            }
        }
        cout<<res<<endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/caiyishuai/p/8955261.html

时间: 2024-08-18 10:15:49

四川第七届 D Vertex Cover(二分图最小点覆盖,二分匹配模板)的相关文章

poj 2226 Muddy Fields(二分图最小点覆盖)

B - Muddy Fields Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2226 Description Rain has pummeled the cows' field, a rectangular grid of R rows and C columns (1 <= R <= 50, 1 <= C <

POJ2226 Muddy Fields(二分图最小点覆盖集)

题目给张R×C的地图,地图上*表示泥地..表示草地,问最少要几块宽1长任意木板才能盖住所有泥地,木板可以重合但不能盖住草地. 把所有行和列连续的泥地(可以放一块木板铺满的)看作点且行和列连续泥地分别作为XY部,每一块泥地看作边.这样就构造出了一个二分图. 那么,问题就是在这个二分图中就是选出最少的点覆盖所有的边,即二分图最小点覆盖集,而二分图最小点覆盖集=二分图最大匹配. 1 #include<cstdio> 2 #include<cstring> 3 #include<qu

POJ3041 Asteroids【二分图最小点覆盖】

题目链接: http://poj.org/problem?id=3041 题目大意: 有一个N*N的矩阵,有些格子上有障碍物(坐标为(x,y) ),在消除这些障碍物的时候,可以一次性消除 该障碍物同一行所有的障碍物,或是一次性消除该障碍物同一列所有的障碍物.只能选择清理该行或是 清理该列.问:最小进行多少次消除,就可以清理所有的障碍物. 思路: 可以将每一行当做一个点,这样总共有N个点,作为二分图的一边.将每一列当做一个点,这样又有N 个点,作为二分图的另一边.将有障碍物的行点和列点连接起来,每

hihoCoder #1127 : 二分图二&#183;二分图最小点覆盖和最大独立集

#1127 : 二分图二·二分图最小点覆盖和最大独立集 Time Limit:10000ms Case Time Limit:1000ms Memory Limit:256MB 描述 在上次安排完相亲之后又过了挺长时间,大家好像都差不多见过面了.不过相亲这个事不是说那么容易的,所以Nettle的姑姑打算收集一下之前的情况并再安排一次相亲.所以现在摆在Nettle面前的有2个问题: 1.姑姑想要了解之前所有相亲的情况.对于任一个一次相亲,只要跟参与相亲的两人交流就可以得到这次相亲的情况.如果一个人

POJ1325_Machine Schedule(二分图/最小点覆盖=最大匹配)

解题报告 http://blog.csdn.net/juncoder/article/details/38147135 题目传送门 题意: A机器有n个模式,B机器有m个模式,每个作业可以在任何机器的特定模式下工作,转换模式需要耗时,求最小耗时 思路: 把AB两机器的模式当成二分图顶点,模式之间的连线就是某个作业可以在该两个模式下工作,就转换成求最小点覆盖,用最少的点覆盖最多的边. 最小点覆盖=最大匹配 #include <queue> #include <cmath> #incl

HDU2119_Matrix(二分图/最小点覆盖=最大匹配)

解题报告 题目传送门 题意: 题意类似与POJ3041 思路: 见POJ3041解题报告 最小点覆盖. #include <iostream> #include <cstring> #include <cstdio> using namespace std; int mmap[110][110],vis[110],pre[110],n,m; int dfs(int x) { for(int i=1; i<=m; i++) { if(!vis[i]&&

nyoj 游戏高手的烦恼 (二分图最小点覆盖)

还是想半天都没想明白.. 做得不多不熟,所以也联系不起来. 二分图最小点覆盖= 二分图的匹配数  详细请看某周的hihocoder 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<string> 6 #include<queue> 7 #include<algorithm> 8 #inclu

hihoCoder #1127:二分图最小点覆盖和最大独立集

题目大意:求二分图最小点覆盖和最大独立集. 题目分析:如果选中一个点,那么与这个点相连的所有边都被覆盖,使所有边都被覆盖的最小点集称为最小点覆盖,它等于最大匹配:任意两个点之间都没有边相连的最大点集称为最大独立集,它等于总节点数减去最大匹配数. 代码如下: # include<iostream> # include<cstdio> # include<cmath> # include<vector> # include<list> # inclu

二分图最小点覆盖的证明

[装载自:http://blog.sina.com.cn/s/blog_5ceeb9ea0100l08n.html] 首先,回顾一下二分图最小点覆盖的定义 二分图中,选取最少的点数,使这些点和所有的边都有关联(把所有的边的覆盖),叫做最小点覆盖.最少点数=最大匹配数 结合昨天看的介绍,,今天按照我的理解给出自己的证明(原创,仅作参考,欢迎讨论) 从最大匹配数到底能不能覆盖所有的边入手. 因为已知了最大匹配,所有再也不能找到增广路了,有最大匹配定义知. 现在所有的边就剩下两种情况了,一种是匹配,一