The 7th Sichuan D Vertex Cover (minimum point coverage of bipartite graph, bipartite matching template)

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 ( b m ) ) (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{a i , b i } 30 1≤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

The meaning of the question: there are n points and m edges, each edge has at least one vertex dyed, and at least how many points should be dyed

Idea: minimum point coverage of bipartite graph, there is a formula bipartite graph maximum matching = minimum point coverage, the Hungarian algorithm came out in one generation

#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 ; // mark asked 
    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))
        { // if it didn't match or (did not ask and could find others) 
            match[x]= y;
            match[y]=x;
            return 1;
        }
    }
    return 0;
}
intmain ()
{
    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 ) // not yet matched 
            {
                memset(used, 0 , sizeof (used)); // initialize every time 
                if (dfs(i))
                 // if it can match 
                    res++ ;
                }
            }
        }
        cout<<res<<endl;
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324896011&siteId=291194637