HDU 1054 Strategic Game 最小点覆盖

   最小点覆盖概念:选取最小的点数覆盖二分图中的所有边。

   最小点覆盖 = 最大匹配数。

   证明:首先假设我们求的最大匹配数为m,那么最小点覆盖必然 >= m,因为仅仅是这m条边就至少需要m个点。然后假如我们已经求得最小覆盖点集,那么在点集中每个点必然有着这样的性质,在于它相连的边里面,一定有一条边的端点不在最小点集中,因为如果连一条这样的边都没有,那这个点完全没有在最小点集的必要,我们任意选取这样的一条边,一定可以形成一个匹配,匹配数与最小点集中的点的个数相等,但现在这仅仅是一个匹配,他必然小于最大匹配,所以最小点覆盖 <= m,综上所述,最小点覆盖 = 最大匹配数,证明成立。

   ps:这个证明是我从网上看明白后总结出来的,个人感觉学姐的证明过于笼统,所以就放在了这里,感觉这个更加严密易懂(学知识要学明白嘛~)。

   代码如下:实现方法:基础匈牙利算法。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 1510
int n;
struct EDGE
{
    int to,nxt;
} edge[10*maxn];
int head[maxn],vis[maxn],match[maxn],tot;
void add_edge(int u,int v)
{
    edge[tot].to = v;
    edge[tot].nxt = head[u];
    head[u] = tot++;
}
bool Find(int u)
{
    for(int i = head[u]; i != -1; i = edge[i].nxt)
    {
        int v = edge[i].to;
        if(!vis[v])
        {
            vis[v] = 1;
            if(match[v] == -1 || Find(match[v]))
            {
                match[v] = u;
                return true;
            }
        }
    }
    return false;
}
int slove()
{
    memset(match,-1,sizeof(match));
    int ans = 0;
    for(int i = 0; i < n; i++)
    {
        memset(vis,0,sizeof(vis));
        if(Find(i))
            ans++;
    }
    return ans;
}
int main()
{
    int num,a,b,t;
    while(~scanf("%d",&t))
    {
        n = t;
        memset(head,-1,sizeof(head));
        tot = 0;
        while(t--)
        {
            scanf("%d:(%d)",&a,&num);
            for(int i = 0;i < num;i++)
            {
                scanf("%d",&b);
                add_edge(a,b);
                add_edge(b,a);
            }
        }
        int ans = slove()/2;
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-10-12 18:34:19

HDU 1054 Strategic Game 最小点覆盖的相关文章

hdu 1054 Strategic Game (最小顶点覆盖+稀疏图)

Strategic Game Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4889    Accepted Submission(s): 2225 Problem Description Bob enjoys playing computer games, especially strategic games, but some

hdu 1054 Strategic Game (二分匹配)

Strategic Game Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4697    Accepted Submission(s): 2125 Problem Description Bob enjoys playing computer games, especially strategic games, but somet

POJ 1463 Strategic game 最小点覆盖集(树形dp)

点击打开链接 Strategic game Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 6105   Accepted: 2808 Description Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the solution fast enough and then he is v

hdu 1054 Strategic Game 二分图最小点覆盖

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1054 题意: 给出一个无向图,求最小点覆盖. 思路: 用网络流来做设立一个超级源点和一个超级汇点. 每个点拆成i和i'. 从超级源点向点i连一条边,容量为1. 从i’向超级汇点连一条边,容量为1. 从i向i'连一条边,容量为正无穷. 然后求最小割/2.因为拆点拆成了2个. 也可以用二分图匹配来做,也是求出最大匹配然后/2. 1 #include <bits/stdc++.h> 2 using na

HDU——1054 Strategic Game

Strategic Game Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 8504    Accepted Submission(s): 4094 Problem Description Bob enjoys playing computer games, especially strategic games, but some

POJ1463 Strategic game (最小点覆盖 or 树dp)

题目链接:http://poj.org/problem?id=1463 给你一棵树形图,问最少多少个点覆盖所有的边. 可以用树形dp做,任选一点,自底向上回溯更新. dp[i][0] 表示不选i点 覆盖子树所有边的最少点个数,那选i点的话,那么i的邻接节点都是必选的,所以dp[i][0] += dp[i.son][1] dp[i][1] 表示选i点 覆盖子树所有边的最少点个数,那么i的邻接点可选可不选(而不是一定不选,看注释样例就知道了),所以dp[i][0] += min(dp[i.son][

HDU 1054 Strategic Game (树形dp)

题目链接 题意: 给一颗树,用最少的点覆盖整棵树. 分析: 1:以当前节点为根节点,在该节点排士兵守护道路的最小消耗.在这种情况下,他的子节点可以安排士兵,也可以不安排士兵.可以从各个子节点两个不同状态(存在士兵,不存在士兵)的最值中选出最小的消耗,然后相加就求出了当前节点派士兵的最小消耗. 2:以当前节点为根节点,不存在士兵.这种情况十分清楚,因为当前节点没有士兵,那么这个节点到子节点之间的道路没有人守护,那么子节点就必须要安排士兵,因此这种情况下.这个节点的最小消耗就是每个子节点存在士兵的情

hdu - 1054 - Strategic Game(树形dp)

题意:一棵n个结点的无根树(0 < n <= 1500),在一个结点放一个士兵,可以守护与这个点相邻的所有边,问最少需要多少个士兵,可以守护所有边. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1054 -->>状态: dp[i][1]表示以 i 为结点的子树,在 i 放一个士兵,可以守护所有边的最少士兵数. dp[i][0]表示以 i 为结点的子树,在 i 不放士兵,可以守护所有边的最少士兵数. 状态转移方程(结点 j 是结点 i

hdu 1054 Strategic Game 【匈牙利算法】

题目链接:http://acm.acmcoder.com/showproblem.php?pid=1054 题意:求无向图的最小顶点覆盖 = 最大匹配数 / 2; 代码: #include <stdio.h> #include <ctime> #include <math.h> #include <limits.h> #include <complex> #include <string> #include <functiona