SCU 4439 Vertex Cover(二分图最小覆盖点)题解

题意:每一条边至少有一个端点要涂颜色,问最少涂几个点

思路:最小顶点覆盖:用最少的点,让每条边都至少和其中一个点关联,显然是道裸最小顶点覆盖题;

参考:二分图

代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#include<vector>
using namespace std;
typedef unsigned long long ull;
const int maxn = 500 + 10;
const ull seed = 131;
struct Edge{
    int v, next;
}edge[maxn * maxn * 2];
int head[maxn], match[maxn], vis[maxn], tot;
void addEdge(int u, int v){
    edge[tot].v = v;
    edge[tot].next = head[u];
    head[u] = tot++;
}
bool dfs(int u){
    for(int i = head[u]; i != -1; i = edge[i].next){
        int v = edge[i].v;
        if(!vis[v]){
            vis[v] = 1;
            if(match[v] == -1 || dfs(match[v])){
                match[v] = u;
                match[u] = v;
                return true;
            }
        }
    }
    return false;
}
int solve(int n){
    int ans = 0;
    memset(match, -1, sizeof(match));
    for(int i = 1; i <= n; i++){
        if(match[i] == -1){
            memset(vis, 0, sizeof(vis));
            if(dfs(i)) ans++;
        }
    }
    return ans;
}
int main(){
    int n, m;
    while(~scanf("%d%d", &n, &m)){
        memset(head, -1, sizeof(head));
        tot = 0;
        for(int i = 1; i <= m; i++){
            int u, v;
            scanf("%d%d", &u, &v);
            addEdge(u, v);
            addEdge(v, u);
        }
        printf("%d\n", solve(n));
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/KirinSB/p/9898786.html