POJ3659 Cell Phone Network【最小支配集】【贪心】

Cell Phone Network

Time Limit: 1000MS
Memory Limit: 65536K

Total Submissions: 5735Accepted: 2053

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

Source

USACO 2008 January Gold

题目大意:John想让他的所有牛用上手机以便相互交流(也是醉了。。。),他需要建立

几座信号塔在N块草地中。已知与信号塔相邻的草地能收到信号。给你N-1个草地(A,B)

的相邻关系,问:最少需要建多少个信号塔能实现所有草地都有信号。

思路:考察树最小支配集问题。最小支配集:值从所有顶点中取尽量少的点组成一个集

合,使得剩下的所有点都与取出来的点有边相连。顶点个数最小的支配集被称为最小支

配集。这里用贪心法来求。

1.以1号点深度优先搜索整棵树,求出每个点在DFS中的编号和每个点的父亲节点编号。

2.按DFS的反向序列检查,如果当前点既不属于支配集也不与支配集中的点相连,且它

的父亲也不属于支配集,将其父亲点加入支配集,支配集个数加1。

3.标记当前结点、当前结点的父节点(属于支配集)、当前结点的父节点的父节点(与支配集

中的点相连)。

参考:ACM-ICPC程序设计系列——图论及应用 P66~P69

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 20020;

struct EdgeNode
{
    int to;
    int next;
}Edges[MAXN];
int Head[MAXN],father[MAXN],NewPos[MAXN];
bool vis[MAXN];
//NewPos[]表示深度优先遍历序列的第i个点是哪个点
//now表示当前深度优先遍历序列中已经有多少个点了
//vis[]用来深度优先遍历的判重
//father[]表示点i的父亲节点编号
int N,M,now;
void DFS(int x)
{
    NewPos[now++] = x;
    for(int k = Head[x]; k != -1; k = Edges[k].next)
    {
        if(!vis[Edges[k].to])
        {
            vis[Edges[k].to] = true;
            father[Edges[k].to] = x;
            DFS(Edges[k].to);
        }
    }
}

//S[i]为true,表示第i个点被覆盖了
//Set[i]表示点i属于要求的点集
bool S[MAXN],Set[MAXN];
int Greedy()//贪心求最小支配集
{
    memset(S,0,sizeof(S));
    memset(Set,0,sizeof(Set));
    int ans = 0;
    for(int i = N-1; i >= 1; i--)//反向序列检查
    {
        int t = NewPos[i];
        if(!S[t])//当前点未被覆盖,也就是当前点既不属于支配集,夜不语支配集中的点相连
        {
            if(!Set[father[t]])//当前点的父亲结点不属于支配集,
            {
                Set[father[t]] = true;  //将父节点加入支配集
                ans++;                  //支配集个数加1
            }
            S[t] = true;
            S[father[t]] = true;
            S[father[father[t]]] = true;
            //标记当前点、当前结点的父节点、当前结点的父节点的父节点
        }
    }
    return ans;
}

int main()
{
    int u,v;
    while(~scanf("%d",&N))
    {
        memset(Edges,0,sizeof(Edges));
        memset(Head,-1,sizeof(Head));
        memset(father,0,sizeof(father));
        memset(vis,false,sizeof(vis));
        memset(NewPos,0,sizeof(NewPos));
        int id = 0;
        for(int i = 0; i < N-1; ++i)
        {
            scanf("%d%d",&u,&v);
            Edges[id].to = v;
            Edges[id].next = Head[u];
            Head[u] = id++;
            Edges[id].to = u;
            Edges[id].next = Head[v];
            Head[v] = id++;
        }
        now = 0;
        vis[1] = true;
        father[1] = 1;
        DFS(1);
        printf("%d\n",Greedy());
    }

    return 0;
}
时间: 2024-09-29 22:08:42

POJ3659 Cell Phone Network【最小支配集】【贪心】的相关文章

【POJ3659】【USACO 2008 Jan Gold】 3.Cell Phone Network 树上最小支配集/贪心 两种做法

题意:求树上最小支配集 最小支配集:点集,即每个点可以"支配"到相邻点,求最少点数可以使所有点被支配. 图上的最小支配集是NP的,但是树上的可以DP做,是O(n)的. 暴力做就好了, f[i]表示此 点被选时的子树全支配的最小代价 g[i]表示其父亲节 点被选时的子树全支配的最小代价 h[i]表示其某子节 点被选时的子树全支配的最小代价 然后暴力转移. (v是子节点) f[x]=∑(min(f[v],min(g[v],h[v])))+1; g[x]=∑(min(f[v],h[v]));

贪心法求树的最小支配集,最小点覆盖,最大独立集

定义: 最小支配集:对于图G = (V, E) 来说,最小支配集指的是从 V 中取尽量少的点组成一个集合, 使得 V 中剩余的点都与取出来的点有边相连.也就是说,设 V' 是图的一个支配集,则对于图中的任意一个顶点 u ,要么属于集合 V', 要么与 V' 中的顶点相邻. 在 V' 中除去任何元素后 V' 不再是支配集, 则支配集 V' 是极小支配集.称G 的所有支配集中顶点个数最少的支配集为最小支配集,最小支配集中的顶点个数称为支配数. 最小点覆盖:对于图G = (V, E) 来说,最小点覆盖

POJ 3659 Cell Phone Network(树的最小支配集)(贪心)

Cell Phone Network Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6781   Accepted: 2429 Description Farmer John has decided to give each of his cows a cell phone in hopes to encourage their social interaction. This, however, requires hi

POJ3659 Cell Phone Network(树上最小支配集:树型DP)

题目求一棵树的最小支配数. 支配集,即把图的点分成两个集合,所有非支配集内的点都和支配集内的某一点相邻. 听说即使是二分图,最小支配集的求解也是还没多项式算法的.而树上求最小支配集树型DP就OK了. 树上的每个结点作为其子树的根可以有三个状态: 不属于支配集且还没被支配 不属于支配集但被其孩子支配 属于支配集 那么就是用dp[u][1\2\3]来表示动归的状态. 123转移该怎么转移就怎么转移..最后的结果就是min(dp[root][2],dp[root][3]). 要注意的是对于有些结点前2

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

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

最小支配集: 从V中选取尽量少的点组成一个集合,让V中剩余的点都与取出来的点有边相连. (点) 最小点覆盖: 从V中选取尽量少的点组成一个集合V1,让所有边(u,v)中要么u属于V1,要么v属于V1 (边) 最大独立集: 从V中选取尽量多的点组成一个集合,让这些点中间没有边项链,也就是说对于任何一条边,u,v不能同时属于集合V1. 1.贪心算法 首先选取一个点为根节点,求出所有节点对应的DFS序列,按照所得序列反向进行贪心,这样保证对于每个点来说,当子树都被处理过之后才会处理该节点 int p[

树的最小支配集,最小点覆盖,最大独立集两种算法

1.基本概念 对图G=<V,E>, 最小支配集:从V中取尽量少的点组成一个集合,使得V中剩余的点都与取出来的点有边相连 最小点覆盖:从V中取尽量少的点组成一个集合,使得E中所有边都与取出来的点相连 最大独立集:从V中取尽量多的点组成一个集合,使得这些点之间没有边相连 2.贪心法求树的最小支配集,最小点覆盖,最大独立集模板 基本算法: 以最小支配集为例,首先选择一点为根,按照深度优先遍历得到遍历序列,按照所得序列的反向序列的顺序进行贪心,对于一个既不属于支配集也不与支配集中的点相连的点来说,如果

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

最小支配集:指从所有顶点中取尽量少的点组成一个集合,使得剩下的所有点都与取出来的点有边相连.顶点个数最小的支配集被称为最小支配集.这里用贪心法来求. 1.以1号点深度优先搜索整棵树,求出每个点在DFS中的编号和每个点的父亲节点编号. 2.按DFS的反向序列检查,如果当前点既不属于支配集也不与支配集中的点相连,且它的父亲也不属于支配集,将其父亲点加入支配集,支配集个数加1. 3.标记当前结点.当前结点的父节点(属于支配集).当前结点的父节点的父节点(与支配集中的点相连). #include<ios

树的最小支配集 最小点覆盖 与 最大独立集 (图论)

做 战略游戏 这道题的时候看到了这个东西,于是就来这里写了一下. 首先看一下三者的定义: 定义1 对于图G=(V,E)来说,最小支配集指的是从V中取尽量少的点组成一个集合,使得对于V中剩余的点都与取出来的点有边相连.也就是说,设V‘是图G的一个支配集,则对于图中的任意一个顶点u,要么属于集合V’,要么与V‘中的顶点相邻.在V’中出去任何元素后V‘不再是支配集,则支配集是极小支配集.称G的所有支配集中顶点个数最少的支配集为最小支配集,最小支配集中顶点的个数称为支配数. 定义2 对于图G=(V,E)