POJ 3659/洛谷 P2899 [USACO08JAN]手机网络Cell Phone Network 树的最小的支配集(树型DP)


                                                              Cell Phone Network 

Time Limit: 1000MS

Memory Limit: 65536K

Total Submissions: 7165

Accepted: 2558

Description

Farmer John has decided to give each of his cows a cell phone inhopes to encourage their social interaction. This, however, requires him to setup cell phone towers on his N (1 ≤ N ≤ 10,000) pastures (convenientlynumbered 1..N) so they can all communicate.

Exactly N-1pairs of pastures are adjacent, and for any two pastures A and B (1 ≤ A ≤ N;1 ≤ B ≤ NA ≠ B)there is a sequence of adjacent pastures such that isthe first pasture in the sequence and B is the last. Farmer John can onlyplace cell phone towers in the pastures, and each tower has enough range toprovide service to the pasture it is on and all pastures adjacent to thepasture with the cell tower.

Help him determine the minimum number of towers he must install toprovide cell phone service to each pasture.

Input

* Line 1: A single integer: N
* Lines 2..N: Each line specifies a pair of adjacent pastures with twospace-separated integers: A and B

Output

* Line 1: A single integer indicating the minimum number of towersto install

SampleInput

5
1 3
5 2
4 3
3 5

SampleOutput

2

Source

USACO 2008 January Gold

算法分析:

具体解释(点这里

贪心做法(点这里

代码实现:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstdlib>
#include<queue>
#include<vector>
#define INF 0x7fffffff
#define PI acos(-1.0)
#define N 10025
#define MOD 2520
#define E 1e-12
using namespace std;
#define N 100005
int f[N][3],n,vis[N];
vector<int> g[N];
int dp(int u)
{

    f[u][0]=1;
    f[u][1]=0;
    f[u][2]=0;
    vis[u]=1;
    bool flag=0;
    int inc=INF;

    for(int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];

        if(vis[v]==0)
        {

            dp(v);
        f[u][0]+=min(f[v][0],min(f[v][1],f[v][2]));
        f[u][2]+=min(f[v][0],f[v][1]);

        if(f[v][0]<=f[v][1])
          {
            flag=1;
            f[u][1]+=f[v][0];
          }
          else
          {
              inc=min(inc,(f[v][0]-f[v][1]));
              f[u][1]+=f[v][1];
          }
        }
    }
    if(flag==0)//f[u][1]没有从f[v][0]推过来,强制转化为从f[v][0]推过来
        f[u][1]+=inc;
    return 0;
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        memset(f,0,sizeof(f));
            memset(vis,0,sizeof(vis));
      for(int i=1;i<n;i++)
      {
          int x,y;
          scanf("%d%d",&x,&y);
          g[x].push_back(y);
          g[y].push_back(x);
      }
      dp(1);
      printf("%d",min(f[1][0],f[1][1]));
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值