UVa 2038 - Strategic game(二分图最小顶点覆盖 or 树形DP)

Strategic game

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.

For example for the tree:

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

Input

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_identifiernumber_of_roads

    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.

    Output

    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).

    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
    

    题意:给定一棵树,选择尽量少的点,使得每个没有选中的结点至少和一个已经选中的结点相邻。输出最少需要选择的节点数。

    思路:经典的二分图最小顶点覆盖, 也是经典的树形 DP 。

    最小顶点覆盖 == 最大匹配(双向图)/2

    数据较大,用邻接表。不然会超时。

    <span style="font-size:18px;">#include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <cmath>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <set>
    #include <map>
    using namespace std;
    
    const int MAXN = 1510;
    int nx, ny;
    int used[MAXN];
    int cx[MAXN], cy[MAXN];
    vector<int>g[MAXN];
    
    int Find(int u)
    {
        for(int i = 0; i < g[u].size(); i++)
        {
            int v = g[u][i];
            if(!used[v])
            {
                used[v] = 1;
                if(cy[v]==-1 || Find(cy[v]))
                {
                    cy[v] = u;
                    cx[u] = v;
                    return 1;
                }
            }
        }
        return 0;
    }
    
    int Hungary()
    {
        int res = 0;
        memset(cx, -1, sizeof(cx));
        memset(cy, -1, sizeof(cy));
        for(int i = 0; i < nx; i++)
        {
            if(cx[i] == -1)
            {
                memset(used, 0, sizeof(used));
                if(Find(i))
                    res++;
            }
        }
        return res;
    }
    
    int main()
    {
        //freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout);
        int t, n, num;
        int x, y;
        while(cin>>n)
        {
            if(!n)
                break;
            ny = nx = n;
            t = n;
            for(int i = 0; i < n; i++)
                g[i].clear();
            while(t--)
            {
                scanf("%d:(%d)", &x, &num);
                while(num--)
                {
                    scanf("%d", &y);
                    g[x].push_back(y);
                    g[y].push_back(x);
                }
            }
            printf("%d\n", Hungary()/2);
        }
        return 0;
    }
    </span>

    时间: 2024-12-10 18:40:20

    UVa 2038 - Strategic game(二分图最小顶点覆盖 or 树形DP)的相关文章

    HDU ACM 1054 Strategic Game 二分图最小顶点覆盖?树形DP

    分析:这里使用树形DP做. 1.最小顶点覆盖做法:最小顶点覆盖 == 最大匹配(双向图)/2. 2.树形DP: dp[i][0]表示i为根节点,并且该节点不放,所需的最少的点数. dp[i][1]表示i为根节点,并且该节点放,所需要的最少的点数. dp[i][0]=sum(dp[son[i][j]][1]) 该点不放,则它的儿子节点必须都放,只有这样之间的边才可以被覆盖. dp[i][1]=sum(min(dp[son[i][j]][0],dp[son[i][j]][1])) 该点放的话,则它的

    hdu 1150 Machine Schedule(二分图-最小顶点覆盖)

    Machine Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5424    Accepted Submission(s): 2691 Problem Description As we all know, machine scheduling is a very classical problem in compu

    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

    uva 1484 - Alice and Bob&#39;s Trip(树形dp)

    题目链接:uva 1484 - Alice and Bob's Trip 题目大意:Alice和Bob小两口一起出去旅行,他们从0城市出发,Bob喜欢走比较远的路,因为他是个勤奋的好孩子,Alice喜欢走比较近的路,因为她是一个不勤奋的坏孩子,所以有了意见上的分歧,于是乎在出门前他们约法三章,要求说最后的距离值在[l,r]之间,并且由夫妻两轮流做决定,决定说下一个城市去哪里.现在给出n个城市,以及n-1条边,问说在不让Bob媳妇生气的情况下,Bob最远能走多远(不违反约定),如果无法做到不违反约

    poj3041 Asteroids(二分图最小顶点覆盖、二分图匹配)

    Description Bessie wants to navigate her spaceship through a dangerous asteroid field in the shape of an N x N grid (1 <= N <= 500). The grid contains K asteroids (1 <= K <= 10,000), which are conveniently located at the lattice points of the

    poj3659 Cell Phone Network(最小支配集-树形dp)

    题目链接:点击打开链接 题目描述:给定一棵树,从中选取尽量少的点使每个点要么被选中,要么和被选中的点直接相连? 解题思路:树上的最小支配集,树形dp dp[i][0]:选中i作为支配集 dp[i][1]:不选i作为支配集,但其子节点覆盖了i dp[i][2]:不选i作为支配集,而且其子节点没有覆盖i 代码: #pragma comment(linker,"/STACK:1024000000,1024000000") #include <cstdio> #include &l

    POJ1325 Machine Schedule 【二分图最小顶点覆盖】

    Machine Schedule Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11958   Accepted: 5094 Description As we all know, machine scheduling is a very classical problem in computer science and has been studied for a very long history. Scheduli

    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

    UVA - 12186 Another Crisis(工人的请愿书)(树形dp)

    题意:某公司有1个老板和n(n<=105)个员工组成树状结构,除了老板之外每个员工都有唯一的直属上司.老板的编号为0,员工编号为1~n.无下属的员工(叶子)打算签署一项请愿书递给老板,但不能跨级递,只能递给直属上司.当一个中级员工(非叶子)的直属下属中不小于T%的人签字时,他也会签字并且递给他的直属上司.问:要让公司老板收到请愿书,至少需要多少个工人签字? 分析: 1.dfs(u)表示让u给上级发信最少需要多少个工人. 2.需要在u的孩子结点中选择不小于T%的人数,这些人所需的工人签字越少越好,