HDU

题意:就是给出一棵树,然后你要尽可能少的在树上放置士兵,士兵会监视与其相连的结点。问怎样最少放置能够覆盖所有的结点
思路:这道题就是一道最小点覆盖问题,我们就把树看作一种图,然后建立无向图求解。 已知结论最小点覆盖 = 最大匹配数(无向图除以2)

完整代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define IOS ios::sync_with_stdio(0); cin.tie(0);
using namespace std;
const int maxn = 1500;
const int maxm = 1e6+5;
struct Edge
{
    int v,next;
}edge[maxm];
int n;
int top ;
int head[maxn];
int vis[maxn];
int match[maxn];
void add(int u,int v){
    edge[top].v = v;
    edge[top].next = head[u];
    head[u] = top++;
}
bool dfs(int u){
    for(int i = head[u]; ~i;i = edge[i].next){
        int v = edge[i].v;
        if(!vis[v]){
            vis[v] = 1;
            if(!match[v]||dfs(match[v])){
                match[v] = u;
                return true;
            }
        }
    }
    return false;
}
int hungary(){
    int res = 0;
    memset(match,0,sizeof(match));
    for(int i =0;i<n;i++){
        memset(vis,0,sizeof(vis));
        if(dfs(i)) res++;
    }
    return res;
}
void init(){
    top = 0;
    memset(head,-1,sizeof(head));
    memset(edge,0,sizeof(edge));
}
int main(){
    while(~scanf("%d",&n)){
        init();
        for(int i = 0;i<n;i++){
            int a,b;
            scanf("%d:(%d)",&a,&b);
            for(int j =0;j<b;j++){
                int v;
                scanf("%d",&v);
                add(a,v);
                add(v,a);
            }
        }
        int ans = hungary();
        printf("%d
",ans/2);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Tianwell/p/11340998.html