POJ 3659 Cell Phone Network / HUST 1036 Cell Phone Network(最小支配集,树型动态规划,贪心)-贪心做法

POJ 3659 Cell Phone Network / HUST 1036 Cell Phone Network(最小支配集,树型动态规划,贪心)

Description

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

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

Help him determine the minimum number of towers he must install to provide 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 two space-separated integers: A and B

Output

Line 1: A single integer indicating the minimum number of towers to install

Sample Input

5
1 3
5 2
4 3
3 5

Sample Output

2

Http

POJ:https://vjudge.net/problem/POJ-3659
HUST:https://vjudge.net/problem/HUST-1036

Source

最小支配集,树型动态规划,贪心

题目大意

在一棵树上选出最小的点集,使得每个点都满足自己在集合中或相连的点在集合中

解决思路

这道题可以用贪心的方法。

先任意选一个点作为根节点,对树进行一遍dfs,记录下dfs序列。然后逆序求(设当前点为u)。若u还未覆盖,则看u的父亲是否覆盖,若已经覆盖,则把u、u的父亲、u的父亲的父亲都标记为已覆盖;若u的父亲还未覆盖,则将u的父亲放入选出的点集中,并同样把u、u的父亲、u的父亲的父亲标记为覆盖。

最后在集合中的点即为所求。

另外,这道题目还有树上动态规划的做法,在这里

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;

const int maxN=10001;
const int inf=2147483647;

int n;
int cnt;
int dfn[maxN];
int Ord[maxN];
int F[maxN];
vector<int> E[maxN];
bool FG[maxN];//标记某个点是否已经覆盖
bool In_set[maxN];//标记某个点是否被选进集合

void dfs(int u);

int main()
{
    memset(dfn,-1,sizeof(dfn));
    memset(F,0,sizeof(F));
    cin>>n;
    for (int i=1;i<n;i++)
    {
        int x,y;
        cin>>x>>y;
        E[x].push_back(y);
        E[y].push_back(x);
    }
    cnt=0;
    dfs(1);
    int Ans=0;
    memset(In_set,0,sizeof(In_set));
    memset(FG,0,sizeof(FG));
    for (int i=n;i>=1;i--)
    {
        int u=Ord[i];
        if (FG[u]==0)
        {
            if (In_set[F[u]]==0)
            {
                In_set[F[u]]=1;
                Ans++;
            }
            FG[u]=1;
            FG[F[u]]=1;
            FG[F[F[u]]]=1;
        }
    }
    cout<<Ans<<endl;
    return 0;
}

void dfs(int u)
{
    cnt++;
    dfn[u]=cnt;
    Ord[cnt]=u;
    for (int i=0;i<E[u].size();i++)
    {
        int v=E[u][i];
        if (dfn[v]==-1)
        {
            F[v]=u;
            dfs(v);
        }
    }
}
posted @ 2017-07-10 11:17  SYCstudio  阅读(269)  评论(0编辑  收藏  举报