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

VertexCover最小点覆盖
介绍了一个基于二分图的最大匹配问题——VertexCover最小点覆盖问题,并通过匈牙利算法求解,实现每条边至少有一个顶点被染色,以达到最小染色顶点数目的目标。

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 (2n500,1mn(n1)22≤n≤500,1≤m≤n(n−1)2). Each of the following mm lines contains 22 integers ai,biai,bi (1ai,bin,aibi,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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值