HDU1054 Strategic Game(最小点覆盖)

Strategic Game

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 10153    Accepted Submission(s): 4744

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=1054

Description:

Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the solution fast enough and then he is very sad. Now he has the following problem. He must defend a medieval city, the roads of which form a tree. He has to put the minimum number of soldiers on the nodes so that they can observe all the edges. Can you help him?

Your program should find the minimum number of soldiers that Bob has to put for a given tree.

The input file contains several data sets in text format. Each data set represents a tree with the following description:

the number of nodes
the description of each node in the following format
node_identifier:(number_of_roads) node_identifier1 node_identifier2 ... node_identifier
or
node_identifier:(0)

The node identifiers are integer numbers between 0 and n-1, for n nodes (0 < n <= 1500). Every edge appears only once in the input data.

For example for the tree:

the solution is one soldier ( at the node 1).

The output should be printed on the standard output. For each given input data set, print one integer number in a single line that gives the result (the minimum number of soldiers). An example is given in the following table:

Sample Input:

4
0:(1) 1
1:(2) 2 3
2:(0)
3:(0)
5
3:(3) 1 4 2
1:(1) 0
2:(0)
0:(0)
4:(0)

Sample Output:

1
2

题意:

问在图中最少放置多少个士兵,可以看守所有的边。

题解:

最小点覆盖模板。

但由于数据量较大,边数较多,邻接矩阵要超时,我便改用vector存储。

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#define mem(x,y) memset(x,y,sizeof(x))
using namespace std;

const int N = 1505 ;
int check[N],match[N];
int n,ans,dfn;
vector<int> link[N];

inline int dfs(int x){
    for(int i=0;i<link[x].size();i++){
        int now = link[x][i];
        if(check[now]!=dfn){
            check[now]=dfn;
            if(match[now]==-1 || dfs(match[now])){
                match[now]=x;
                return 1;
            }
        }
    }
    return 0;
}

int main(){
    while(scanf("%d",&n)!=EOF){
        for(int i=0;i<n;i++) link[i].clear();
        mem(link,0);mem(match,-1);ans=dfn=0;
        for(int i=0,u,k;i<n;i++){
            scanf("%d:(%d)",&u,&k);
            for(int j=1,v;j<=k;j++){
                scanf("%d",&v);
                link[u].push_back(v);
                link[v].push_back(u);
            }
        }
        for(int i=0;i<n;i++){
            dfn++;
            if(dfs(i)) ans++;
        }
        printf("%d\n",ans/2);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/heyuhhh/p/9926681.html

时间: 2024-10-08 15:42:27

HDU1054 Strategic Game(最小点覆盖)的相关文章

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 最小点覆盖

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

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][

poj1463 Strategic game 树的最小点覆盖

http://poj.org/problem?id=1463 Strategic game Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 6413   Accepted: 2973 Description Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the solution fast

Strategic game POJ - 1463 【最小点覆盖集】

Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the solution fast enough and then he is very sad. Now he has the following problem. He must defend a medieval city, the roads of which form a tree. He has to

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

HDU1054 Strategic Game——匈牙利算法

Strategic Game Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the solution fast enough and then he is very sad. Now he has the following problem. He must defend a medieval city, the roads of which form a t

UVA-11419 SAM I AM (最小点覆盖)

题目大意:在一个n*m的网格中,有k个目标,现在可以任选一行或列消除在其上的所有目标,求出最少选择次数及选法. 题目分析:经典的最小点覆盖问题,并且输出一个最小点覆盖集.在求出最大匹配之后,以未覆盖的x点进行标记,沿着未覆盖->覆盖->未覆盖->覆盖...的路径标记,最后x中未标记的和y中标记的点构成最小点覆盖集. 代码如下: # include<iostream> # include<cstdio> # include<cstring> # incl

POJ2226 Muddy Fields(二分图最小点覆盖集)

题目给张R×C的地图,地图上*表示泥地..表示草地,问最少要几块宽1长任意木板才能盖住所有泥地,木板可以重合但不能盖住草地. 把所有行和列连续的泥地(可以放一块木板铺满的)看作点且行和列连续泥地分别作为XY部,每一块泥地看作边.这样就构造出了一个二分图. 那么,问题就是在这个二分图中就是选出最少的点覆盖所有的边,即二分图最小点覆盖集,而二分图最小点覆盖集=二分图最大匹配. 1 #include<cstdio> 2 #include<cstring> 3 #include<qu