链接:https://ac.nowcoder.com/acm/contest/1069/A
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
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.
输入描述:

  • 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
    输出描述:
  • Line 1: A single integer indicating the minimum number of towers to install
    示例1
    输入
    复制
5
1 3
5 2
4 3
3 5

输出
复制

2

说明
The towers can be placed at pastures 2 and 3 or pastures 3 and 5.

一.题意:

给出直接相连的几条边,选择最少的点,使所有点都被覆盖(点能被覆盖的条件是:与所选点 有边直接相连)
这题实质上是求最小支配集

二.最小支配集的概念:

支配集的定义如下:给定无向图G =(V , E),其中V是点集, E是边集, 称V的一个子集S称为支配集当且仅当对于V-S中任何一个点v, 都有S中的某个点u, 使得(u, v) ∈E。
特别地,最小的支配集S(即任意一个比S小的集合都不可能是支配集)叫做最小支配集

三 .求解最小支配集的方法:

1.类似Tarjan且基于dfs的贪心
2.树形dp

四.具体操作

解法一:
贪心:
1.选择其中一个点作为root,定义father数组,并标记root的父亲为自己。
2.定义一个dfsn数组,用于dfs时记录每个点dfs序
3.dfs,dfs得到dfs序和每个点的father
4.定义一个s数组,作为支配集容器,
重新初始化vis,vis用于标记是否属于支配集和是否与支配集中的点相连
记录答案:按照dfs序的逆序依次选点
对于一个即不属于支配集也不与支配集中的点相连的点来说
,如果他的父节点不属于支配集,将其父节点加入到支配集,ans++,标记当前节点父节点属于支配集s
标记当前结点、当前结点的父节点(属于支配集)、当前结点的父节点的父节点(与支配集中的点相连)。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e4+5;
vector<int>vec[MAXN];
int dfn[MAXN];
bool vis[MAXN];
int father[MAXN];
int s[MAXN];
int cnt;
int n;
void init()
{for(int i = 0; i<= n; i++){vis[i] = false;}
}
void dfs(int s)
{dfn[++cnt] = s ;int iSize = vec[s].size();for(int i = 0; i < iSize; i++){int to = vec[s][i];if(!vis[to]){father[to] = s;vis[to] = true;dfs(to);}}return;
}
int solve()
{father[1] = 1;vis[1] = true;dfs(1);init();int ans = 0;for(int i = cnt; i > 0; i--){int x = dfn[i];if(!vis[x])//不属于支配集也不与支配集中的点相连{if(!s[father[x]])//它的父节点不属于支配集{ans++;s[father[x]] = true;//父节点入支配集}vis[x] = true;//标记自己vis[father[x]] = true;//标记自己的父亲vis[father[father[x]]] = true;//标记自己父亲的父亲}}return ans;
}
int main()
{cin>>n;int x,y;for(int i = 1; i < n; i++){cin>>x>>y;vec[x].push_back(y);vec[y].push_back(x);}cout<<solve()<<endl;return 0;
}

解法二:
dp:(我表示并不会)
请参考下面来自百度百科的代码:

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int MAXN=10010;
const int INF=int(1e7);
struct node
{ int to; int next;
} edge[MAXN*2];
int head[MAXN*2],num;
int dp[MAXN][3];
/*
1):dp[i][0],表示点 i 属于支配集合,
并且以点 i 为根的子树都被覆盖了的情况下支配集中所包含最少点的个数.
2):dp[i][1],表示点 i 不属于支配集合,且以 i 为根的子树都被覆盖,
且 i 被其中不少于一个子节点覆盖的情况下支配集所包含最少点的个数.
3):dp[i][2],表示点 i 不属于支配集合,
且以 i 为根的子树都被覆盖,且 i 没被子节点覆盖的情况下支配集中所包含最少点的个数.即 i 将被父节点覆盖.
*/
int n;
void add(int x,int y)
{ edge[++num].next=head[x]; edge[num].to=y; head[x]=num;
}
void DP( int k,int fat )
{ dp[ k ][ 0 ]=1; dp[ k ][ 2 ]=0; bool s=0; int x,sum=0,inc=INF; for(int i=head[ k ]; i ;i=edge[i].next ) { x=edge[i].to; if( x==fat )    continue ; DP( x,k ); dp[ k ][ 0 ]+=min(dp[ x ][ 0 ],min(dp[ x ][ 1 ],dp[ x ][ 2 ])); if( dp[ x ][ 0 ] <= dp[ x ][ 1 ] ) { sum+=dp[ x ][ 0 ]; s=1; } else { sum+=dp[ x ][ 1 ]; inc=min(inc,dp[ x ][ 0 ]-dp[ x ][ 1 ]); } if( dp[ x ][ 1 ]!=INF && dp[ k ][ 2 ]!=INF ) //x不是叶子节点,而且k有父亲,即k不是根  dp[ k ][ 2 ]+=dp[ x ][ 1 ]; else dp[ k ][ 2 ]=INF; } if( inc==INF && !s )//k没有子节点     dp[ k ][ 1 ]=INF; else { dp[ k ][ 1 ]=sum; if( !s )//如果不为零,则k的子节点中有一个已经染色     dp[ k ][ 1 ]+=inc; } return ;
}
int main()
{ int u,v; scanf("%d",&n); for(int i=1; i<=n-1; i++) { scanf("%d%d",&u,&v); add(u,v); add(v,u); } DP( 1,0 ); int ans=min(dp[1][0],dp[1][1]); printf("%d\n",ans); return 0; 

牛客假日团队赛8:H.Cell Phone Network(最小支配集)相关推荐

  1. 牛客假日团队赛8:F.Telephone Lines(二分+spfa)

    链接:https://ac.nowcoder.com/acm/contest/1069/F 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言6553 ...

  2. 牛客假日团队赛8:K.Cow Contest(最短路(floyd)变形)

    链接:https://ac.nowcoder.com/acm/contest/1069/K 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言6553 ...

  3. 牛客假日团队赛12【为了抽奖闲来做题2】

    A题 链接:https://ac.nowcoder.com/acm/contest/1081/A 来源:牛客网 Bessie is trapped in a triangular maze with ...

  4. 牛客假日团队赛5 F 随机数 BZOJ 1662: [Usaco2006 Nov]Round Numbers 圆环数 (dfs记忆化搜索的数位DP)...

    链接:https://ac.nowcoder.com/acm/contest/984/F 来源:牛客网 随机数 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言6 ...

  5. 牛客假日团队赛10 L 乘积最大 (dp,大数)

    链接:https://ac.nowcoder.com/acm/contest/1072/L?&headNav=acm&headNav=acm 来源:牛客网 乘积最大 时间限制:C/C+ ...

  6. P5200 [USACO19JAN]Sleepy Cow Sorting 牛客假日团队赛6 D 迷路的牛 (贪心)

    链接:https://ac.nowcoder.com/acm/contest/993/E 来源:牛客网 对牛排序 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言 ...

  7. 牛客假日团队赛6 D 迷路的牛 (思维)

    链接:https://ac.nowcoder.com/acm/contest/993/D 来源:牛客网 迷路的牛 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言 ...

  8. 牛客假日团队赛5J 护城河 bzoj 1670: [Usaco2006 Oct]Building the Moat护城河的挖掘 (凸包的周长)...

    链接:https://ac.nowcoder.com/acm/contest/984/J 来源:牛客网 护城河 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言6 ...

  9. 牛客假日团队赛5 K 金币馅饼 (DP 基础题)

    链接:https://ac.nowcoder.com/acm/contest/984/K 来源:牛客网 金币馅饼 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言 ...

最新文章

  1. codeigniter 中使用 phpexcel
  2. android或java timer声明
  3. android 开发中的常见问题
  4. 可变对象 不可变对象区别_对象应该是不可变的
  5. MongoDb随笔,PyMongo简单使用
  6. vue 不识别svg_vue配置svg 图标显示不出来
  7. 计算机系统高级设置在哪里,Win7系统高级设置在哪里
  8. Android Studio导入项目遇到的问题
  9. 微信看一下!搜狐张朝阳官宣狐友APP重新上架
  10. 数据库工作笔记016---Redis、Memcache和MongoDB的区别
  11. python解zuobiaoxi方程_从马尔可夫链到蒙特卡洛-Metropolis方法(Python)
  12. 0918类对象重载,作业5
  13. java讲师助理面试题_面试Java开发师常问到的5个问题(附答案)
  14. redis中字符串(String)类型常见命令操作 (附有示例)
  15. CHM 打开时提示 已取消到该网页的导航
  16. 重新安装固态硬盘后,然后再安装系统至固态硬盘,为何开机后仍然不能从固态硬盘启动系统?
  17. 中文真伟大!竟然有只能看,不能读的文章
  18. 第3章第9节:快速提取幻灯片中的所有图片素材 [PowerPoint精美幻灯片实战教程]
  19. 400分理科学计算机,400分左右的理科大学 高考400分能上什么学校
  20. 【奇奇怪怪bug】Flink 1.10 on yarn ,application 在yarn 显示Running ,webui 显示Failed

热门文章

  1. 如何用文本档编辑c语言,c语言读写word文档
  2. linux cfs,朴素的UNIX之-Linux CFS一个注释
  3. sudo: apt-get:找不到命令_Linux重复执行历史命令方法详解
  4. c语言 char转int_图文并茂,一文讲透C语言结构体内存对齐
  5. spark-1.6.0-cdh5.15.1环境搭建:Local模式和StandAlone
  6. javax.el.ELException: Provider com.sun.el.ExpressionFactoryImpl not found
  7. 你已经是个成熟的985大学了,请不要在大一教 C 语言!
  8. java的static和private_static关键字什么意思?Java中是否可以覆盖一个private或者是static的方法?...
  9. vue 封装dialog_自己封装dialog组件
  10. python游戏代码示例_练习项目20:使用python制作游戏(中)