Poj 3659 Perfect Service【最小支配集、树型dp】

原创 2016年05月30日 12:41:58

Perfect Service

Time Limit: 2000MS

 

Memory Limit: 65536K

Total Submissions: 1499

 

Accepted: 726

Description

A network is composed of N computers connected by N − 1 communication links such that any two computers can be communicated via a unique route. Two computers are said to be adjacent if there is a communication link between them. The neighbors of a computer is the set of computers which are adjacent to it. In order to quickly access and retrieve large amounts of information, we need to select some computers acting as servers to provide resources to their neighbors. Note that a server can serve all its neighbors. A set of servers in the network forms a perfect service if every client (non-server) is served by exactly one server. The problem is to find a minimum number of servers which forms a perfect service, and we call this number perfect service number.

We assume that N (≤ 10000) is a positive integer and these N computers are numbered from 1 to N. For example, Figure 1 illustrates a network comprised of six computers, where black nodes represent servers and white nodes represent clients. In Figure 1(a), servers 3 and 5 do not form a perfect service because client 4 is adjacent to both servers 3 and 5 and thus it is served by two servers which contradicts the assumption. Conversely, servers 3 and 4 form a perfect service as shown in Figure 1(b). This set also has the minimum cardinality. Therefore, the perfect service number of this example equals two.

Your task is to write a program to compute the perfect service number.

Input

The input consists of a number of test cases. The format of each test case is as follows: The first line contains one positive integer, N, which represents the number of computers in the network. The next N − 1 lines contain all of the communication links and one line for each link. Each line is represented by two positive integers separated by a single space. Finally, a 0 at the (N + 1)th line indicates the end of the first test case.

The next test case starts after the previous ending symbol 0. A −1 indicates the end of the whole inputs.

Output

The output contains one line for each test case. Each line contains a positive integer, which is 
the perfect service number.

Sample Input

6

1 3

2 3

3 4

4 5

4 6

0

2

1 2

-1

Sample Output

2

1

Source

Kaohsiung 2006

 

题目大意:有n个电脑,有n-1条边连接电脑,我们为了更好的共享电脑之间的数据,我们需要设立一些服务器,一台服务器可以管理其自己和直接相连边的电脑,问在不能有一台非服务器电脑被两台服务器所管理的条件下,最少设立多少台服务器可以达到所有电脑都有所覆盖的数目。


思路:明显的最小支配集问题,我们用树型dp来做这个题,


思路:这是个经典的最小支配集的问题,可以用贪心来解决,也可以用树型dp来搞定,我们这里来详解一下树型dp如何实现。

1、首先既然是dp问题,首先我们要设计dp的数组和其含义:

dp【u】【0】表示点u属于支配集,并且以u为根节点的子树已经全部被覆盖。

dp【u】【1】表示点u不属于支配集,并且以u为根节点的子树已经全部覆盖,并且点u被至少其一个子节点所支配。

dp【u】【2】表示点u不属于支配集,并且以u为根节点的子树已经全部覆盖,并且点u没有被其子节点所支配。(那么不难理解,这个点要被其父节点所支配)


2、对数组进行设计完毕之后,我们就要来考虑状态转移过程,分别讨论三种dp数组是如何转移过来:

无论哪种状态,其想要达到的目的是:以u为根节点,并且包含节点u在内的子树都被支配覆盖


dp【u】【0】:dp【u】【0】表示点u属于支配集,但是其子节点不能被两个点覆盖,所以这种情况下,其子节点要么是属于支配集的点,要么是没有被其子节点的子节点有所覆盖的点,辣么不难理解其状态转移方程为:

dp【u】【0】+=1+枚举所有子节点min(dp【v】【0】,dp【v】【2】)


dp【u】【1】:dp【u】【1】表示点u不属于支配集,但是点u被支配着,所以其支配来源一定是从子节点来的,只要其子节点中只要有一个节点属于支配集,那么当前节点u就会被支配,也就是说以u为根节点的子树包含u在内,所有节点都背覆盖了,达到目的。那么不难理解,dp【u】【1】的来源可能是dp【v】【0】或者是dp【v】【1】,并且满足至少一个来源是dp【v】【0】即可。

辣么其状态转移方程:

当然,如果节点u没有子节点:

dp【u】【1】=INF;

如果节点u有子节点:

dp【u】【1】+=枚举所有子节点min(dp【v】【0】,dp【v】【1】)//并且保证其状态转移过程中至少有一个来源于dp【v】【0】,具体参考代码实现。


dp【u】【2】:dp【u】【2】表示点u不属于支配集,并且点u不被其任一子节点所支配,那么其来源就只能是dp【v】【1】或者是dp【v】【2】,但是如果来源是dp【v】【2】的话,那么我们就不能保证两个节点被同时支配了,所以dp【u】【2】只能来源于dp【v】【1】。

d辣么其状态转移方程:
dp【u】【2】+=枚举所有子节点dp【v】【1】;其中任一dp【v】【1】==INF,那么dp【u】【2】=INF。


辣么不难理解,ans=min(dp【root】【0】,dp【root】【1】,1+dp【root】【2】);


3、根节点的确定:我们不妨建立成双向图,那么任何一个点都可以做为根节点向下递归求解。


AC代码:


#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define INF 0x1f1f1f1f
int head[100000];
struct EdgeNode
{
    int to;
    int w;
    int next;
}e[100000];
int cont;
int dp[5000000][3];
int vis[500000];
void add(int from,int to)
{
    e[cont].to=to;
    e[cont].next=head[from];
    head[from]=cont++;
    e[cont].to=from;
    e[cont].next=head[to];
    head[to]=cont++;
}
void Dp(int u)
{
    dp[u][2]=0;
    dp[u][1]=0;
    dp[u][0]=1;
    int sum=0,inc=INF;
    vis[u]=1;
    bool judge=false;
    for(int k=head[u];k!=-1;k=e[k].next)
    {
        int to=e[k].to;
        if(vis[to]==1)continue;
        Dp(to);
        dp[u][0]+=min(dp[to][0],dp[to][2]);
        if(dp[to][0]<=dp[to][1])
        {
            sum+=dp[to][0];
            judge=true;
        }
        else
        {
            sum+=dp[to][1];
            inc=min(inc,dp[to][0]-dp[to][1]);
        }
        if(dp[to][1]!=INF&&dp[u][2]!=INF)dp[u][2]+=dp[to][1];
        else dp[u][2]=INF;
    }
    if(inc==INF&&judge==false)dp[u][1]=INF;
    else
    {
        dp[u][1]=sum;
        if(judge==false)dp[u][1]+=inc;
    }
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        memset(head,-1,sizeof(head));
        memset(vis,0,sizeof(vis));
        memset(dp,0,sizeof(dp));
        cont=0;
        for(int i=0;i<n-1;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            add(x,y);
        }
        int op;
        scanf("%d",&op);
        Dp(1);
        printf("%d\n",min(min(dp[1][0],dp[1][1]),dp[1][2]+1));
        if(op==-1)break;
    }
}







版权声明:0.0小白有写的不好不对的地方请指出~

POJ 3659 树形DP,最小支配集

/** [树形DP] poj 3659 Cell Phone Network 给定一棵树,求最小支配集 dp[i][0] = sum(min(dp[s][2],dp[s][1]))自己没被选,父节点被...
  • hiding_nya
  • hiding_nya
  • 2015年05月14日 11:13
  • 87

poj 3659 树形dp 最小支配集

poj 3659 树形dp 最小支配集
  • u010790071
  • u010790071
  • 2013年10月25日 21:36
  • 830

poj 3398 Perfect Service(最小支配集树形DP)

题目链接:http://poj.org/problem?id=3398
  • u013903504
  • u013903504
  • 2014年09月02日 14:15
  • 483

POJ 3398 Perfect Service【最小支配集修改 dp】

Perfect Service Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 1497   Accepted: ...
  • wyjwyl
  • wyjwyl
  • 2016年05月18日 21:36
  • 394

树的最小支配集

/** 最小支配集,就是图中用最少的点覆盖其它所有点 如果用选A点覆盖,则与A点相连的点都被覆盖,大致 就是这样 百度里面搜到一道题 有一个图G,现在希望在一些...
  • zcube
  • zcube
  • 2015年09月07日 19:53
  • 1170

POJ 3659 贪心 最小支配集

//给你一棵无向树,问你最少用多少个点可以覆盖掉所有其他的点。 // //(一个点被盖,它自己和与它相邻的点都算被覆盖) // //解题报告: // //贪心,随便找一个根,后续遍历树。 //每个点,...
  • hiding_nya
  • hiding_nya
  • 2015年05月14日 11:12
  • 243

poj 3659 树形dp(树上的最小支配集)

题意:求树的最小支配集。 思路:动态规划。一开始每个点只取了两个变量,表示在以其为根的子树中选择和不选择该点的最少点数。由一组数据(6个点的路径)发现了问题,考虑第3个点的时候,如果不选择此点,那么...
  • dumeichen
  • dumeichen
  • 2015年08月29日 17:41
  • 167

树的最小支配集、最小点覆盖、最大独立集【模板】

最小支配集:指从所有顶点中取尽量少的点组成一个集合,使得剩下的所有点都与取出来的点有边相连。顶点个数最小的支配集被称为最小支配集。 最小点覆盖:指从所有顶点中取尽量少的点组成一个集合,使得集合中所有的...
  • u011676797
  • u011676797
  • 2015年05月04日 11:46
  • 1093

bzoj 2324(最小费用最大流)

2324: [ZJOI2011]营救皮卡丘 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 2137  Solved: 873 [Submit]...
  • M_AXSSI
  • M_AXSSI
  • 2016年07月18日 14:51
  • 154

树的最小支配集,最小点覆盖与最大独立集

首先看一下三者的定义: 定义1 对于图G=(V,E)来说, 最小支配集 指的是从V中取尽量少的点组成一个集合,使得对于V中剩余的点都与取出来的点有边相连。也就是说,设V‘是图G的一个支配集,则对于图...
  • M_AXSSI
  • M_AXSSI
  • 2016年03月06日 15:15
  • 1232
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Poj 3659 Perfect Service【最小支配集、树型dp】
举报原因:
原因补充:

(最多只允许输入30个字)