*【POJ - 3659】Cell Phone Network (树形dp,最小支配集)

题干:

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 ≤ NA ≠ B) there is a sequence of adjacent pastures such that 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

解题报告:

由于这是在树上求最值的问题,显然可以用树形动态规划,只是状态的设计比较复杂。为了保证动态规划的正确性,对于每个点设计了三种状态,这三种状态的意义如下:

①dp[i][2]:表示点i属于支配集,并且以点i为根的子树都被覆盖了的情况下支配集中所包含的的最少点的个数。

②dp[i][1]:i不属于支配集,且以i为根的子树都被覆盖,且i被其中不少于1个子节点覆盖的情况下支配集中所包含最少点的个数。

③dp[i][0]:i不属于支配集,且以i为根的子树都被覆盖,且i没被子节点覆盖的情况下支配集中所包含最少点的个数。

对于第一种状态,dp[i][0]等于每个儿子节点的3种状态(其儿子是否被覆盖没有关系)的最小值之和加1,即只要每个以i的儿子为根的子树都被覆盖,再加上当前点i,所需要的最少点的个数,方程如下:

dp[i][2]=1+Σmin(dp[u][2],dp[u][1],dp[u][0])(p[u]=i).

对于第二种状态,如果点i没有子节点,那么dp[i][1]=INF;否则,需要保证它的每个以i的儿子为根的子树都被覆盖,那么要取每个儿子节点的前两种状态的最小值之和,因为此时i点不属于支配集,不能支配其子节点,所以子节点必须已经被支配,与子节点的第三种状态无关。如果当前所选的状态中,每个儿子都没有被选择进入支配集,即在每个儿子的前两种状态中,第一种状态都不是所需点最少的,那么为了满足第二种状态的定义,需要重新选择点i的一个儿子的状态为第一种状态,这时取花费最少的一个点,即取min(dp[u][2]-dp[u][1])的儿子节点u,强制取其第一种状态,其他儿子节点都取第二种状态,转移方程为:

if(i没有子节点)dp[i][1]=INF

else dp[i][1]=Σmin(dp[u][2],dp[u][1])+inc

其中对于inc有:

if(上面式子中的Σmin(dp[u][2],dp[u][1])中包含某个dp[u][2])inc=0;

else inc=min(dp[u][2]-dp[u][1])。

对于第三种状态,i不属于支配集,且以i为根的子树都被覆盖,又i没被子节点覆盖,那么说明点i和点i的儿子节点都不属于支配集,则点i的第三种状态只与其儿子的第二种状态有关,方程为

dp[i][0]=Σdp[u][1]

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e5 + 5;
const int INF = 0x3f3f3f3f;
int head[MAX];
struct Edge {int to,ne;
} e[MAX];
int tot;
void add(int u,int v) {e[++tot].to =v;e[tot].ne = head[u];head[u] = tot;
}
int Min(int a,int b,int c) {if(a < b) return min(a,c);else return min(b,c);
}
int Min(int a,int b) {return min(a,b);
}
int dp[MAX][3];//0不选并且没有被覆盖掉,1不选但是被覆盖到了,2选 ,(同时要保证子节点全部被覆盖到了) 
void dfs(int cur,int rt) {dp[cur][2] = 1;int flag = 1,tmp=INF;for(int i = head[cur]; i!=-1; i=e[i].ne) {int v = e[i].to;if(v == rt) continue;dfs(v,cur);dp[cur][2] += Min(dp[v][0],dp[v][1],dp[v][2]);dp[cur][0] += Min(dp[v][2],dp[v][1]); //不能由下一层没被覆盖到转移!!if(dp[v][2]<=dp[v][1]) {dp[cur][1]+=dp[v][2];flag=0;} else {dp[cur][1]+=dp[v][1];tmp=min(tmp,dp[v][2]-dp[v][1]);}}if(flag)    //还没有选儿子,加上这个差值,补回一个儿子dp[cur][1]+=tmp;
}
int main() {int n;cin>>n;memset(head,-1,sizeof head);for(int a,b,i = 1; i<=n-1; i++) {scanf("%d%d",&a,&b);add(a,b);add(b,a);}dfs(1,-1);printf("%d\n",Min(dp[1][1],dp[1][2]));return 0 ;
}

但是不是很理解为什么  dp[cur][0] +=dp[v][1];  就WA?

 

他这样写:

按照这个定义:

①dp[i][0]:表示点i属于支配集,并且以点i为根的子树都被覆盖了的情况下支配集中所包含的的最少点的个数。

②dp[i][1]:i不属于支配集,且以i为根的子树都被覆盖,且i被其中不少于1个子节点覆盖的情况下支配集中所包含最少点的个数。

③dp[i][2]:i不属于支配集,且以i为根的子树都被覆盖,且i没被子节点覆盖的情况下支配集中所包含最少点的个数。

void DP(int u,int p) {dp[u][2]=0;dp[u][0]=1;bool s=false;int sum=0,inc=INF;int k;for(k=head[u]; k!=-1; k=edge[k].next) {int to=edge[k].to;if(to==p)continue;DP(to,u);dp[u][0]+=min(dp[to][0],min(dp[u][1],dp[u][2]));if(dp[to][0]<=dp[to][1]) {sum+=dp[to][0];s=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&&!s)dp[u][1]=INF;else {dp[u][1]=sum;if(!s)dp[u][1]+=inc;}
}

也是对的,,,这样就可以   dp[cur][2] 只跟 dp[v][1];有关????why??? 

 


另一个题解:

#include<stdio.h>
#include<string.h>
#define clr(x)memset(x,0,sizeof(x))
int min(int a,int b)
{ return a<b?a:b; }
#define maxn 100005
#define INF 0x1f1f1f1f
struct node
{int to;int next;
}e[1000000];
int tot;
int head[maxn];
int dp[maxn][3];
void add(int s,int u)
{e[tot].to=u;e[tot].next=head[s];head[s]=tot++;
}
// dp[r][0] = min(dp[i][0],dp[i][1],dp[i][2])自身建
// dp[r][1] = min(dp[i][0],dp[i][1]) 子节点建
// dp[r][2] = min(dp[i][0],dp[i][1]) 父节点建
int n;
int v[maxn];
void dfs(int r)
{v[r]=1;int i,k;int flag=1,ff=1,mi=INF,t;dp[r][0]=1;for(i=head[r];i;i=e[i].next){k=e[i].to;if(!v[k]){flag=0;dfs(k);dp[r][0]+=min(dp[k][0],min(dp[k][1],dp[k][2]));if(dp[k][1]>=dp[k][0]){ff=0;dp[r][1]+=dp[k][0];}else {dp[r][1]+=dp[k][1];if(dp[k][0]<mi){mi=dp[k][0];t=dp[k][1];}}dp[r][2]+=min(dp[k][0],dp[k][1]);}}if(ff)dp[r][1]+=mi-t;if(flag){dp[r][0]=1;dp[r][1]=INF;dp[r][2]=0;}
}
int main()
{int a,b,i;while(scanf("%d",&n)!=EOF){tot=1;clr(v);clr(dp);clr(head);for(i=1;i<n;i++){scanf("%d%d",&a,&b);add(a,b);add(b,a);}if(n==1){printf("1\n");continue;}dfs(1);printf("%d\n",min(dp[1][0],dp[1][1]));}return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/440582.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【POJ - 2632】Crashing Robots(模拟)

题干&#xff1a; In a modernized warehouse, robots are used to fetch the goods. Careful planning is needed to ensure that the robots reach their destinations without crashing into each other. Of course, all warehouses are rectangular, and all robots occup…

pandownload用户未登录_Pandownload再度复活,下载速度飙升到10MB/s以上

PanDownload再度复活版&#xff0c;此版镜像服务器由新城旧梦维护卢本伟修改版&#xff0c;基本都是维持在10M/S的下载速度&#xff0c;如果你的宽带够大&#xff0c;下载速度会更快&#xff0c;无需安装即可免费使用&#xff0c;但是需要登陆才能下载。(Pandownload卢本伟修改…

momentjs转换格式_Moment.js+Vue过滤器的使用,各种时间格式转换为YYYY-MM-DD HH:mm:ss格式...

前言这篇文章将Moment.js与vue过滤器连用。如果不会过滤器的朋友&#xff0c;可以先看这篇文章vue过滤器一、Moment.js是什么&#xff1f;Moment.js是JavaScript 日期处理类库。使用场景&#xff1a;vue项目中经常需要将时间戳转换为各种时间格式再显示。二、使用步骤1.安装这里…

【HDU - 1943】Ball bearings(几何问题)

题干&#xff1a; The Swedish company SKF makes ball bearings. As explained by Britannica Online, a ball bearing is “one of the two types of rolling, or anti friction, bearings (the other is the roller bearing). Its function is to connect two machine mem…

mysql显示修改密码_MySQL修改密码

第一种方式&#xff1a;最简单的方法就是借助第三方工具Navicat for MySQL来修改&#xff0c;方法如下&#xff1a;1、登录mysql到指定库&#xff0c;如&#xff1a;登录到test库。2、然后点击上方“用户”按钮。3、选择要更改的用户名&#xff0c;然后点击上方的“编辑用户”按…

mysql 磁盘组_有效管理 ASM 磁盘组空间

ORA-15041: diskgroup space exhausted 对您的数据库环境的直接和间接影响&#xff1f;与 ASM 磁盘组相关的磁盘空间问题和 ORA-15041 错误会ORA-15041: diskgroup space exhausted 对您的数据库环境的直接和间接影响&#xff1f;与 ASM 磁盘组相关的磁盘空间问题和 ORA-15041 …

【HDU - 1561】The more, The Better(树形背包,dp,依赖背包问题与空间优化,tricks)

题干&#xff1a; ACboy很喜欢玩一种战略游戏&#xff0c;在一个地图上&#xff0c;有N座城堡&#xff0c;每座城堡都有一定的宝物&#xff0c;在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物。但由于地理位置原因&#xff0c;有些城堡不能直接攻克&#xff0c;要攻克这些…

【CodeForces - 616C 】The Labyrinth点石成金(并查集,dfs)

题干&#xff1a; 小O无意间发现了一张藏宝图&#xff0c;它跟随藏宝图的指引来到了一个宫殿&#xff0c;宫殿的地板被分成了n*m块格子&#xff0c;每个格子上放置了金子或者石头 藏宝图告诉小O&#xff0c;它可以选择一块石头变成金子&#xff0c;并且带走与变化后的金子联通…

jsp mysql 推荐算法_基于jsp+mysql+Spring+mybatis的SSM协同过滤音乐推荐管理系统(个性化推荐)...

运行环境: 最好是java jdk 1.8&#xff0c;我们在这个平台上运行的。其他版本理论上也可以。IDE环境&#xff1a; Eclipse,Myeclipse,IDEA都可以tomcat环境&#xff1a; 最好是Tomcat 7.x,8.x,9.x版本均可&#xff0c;理论上Tomcat版本不是太老都可以。&#xff0c;我们在这个环…

项目进度计划甘特图_甘特图做项目进度计划的技巧?

原标题&#xff1a;甘特图做项目进度计划的技巧&#xff1f;甘特图怎么做项目进度计划&#xff1f;首先我们先了解一下&#xff0c;什么是甘特图。甘特图(Gantt chart)又称为横道图、条状图(Bar chart)&#xff0c;是由提出者亨利L甘特来命名的。甘特图通过条状图来显示项目&am…

wp config.php mysql_WordPress手动配置wp-config.php文件

前不久在WordPress技术群里看到有人在安装网站程序的时候出现了系统不能自动配置wp-config.php文件的问题&#xff0c;那么这个时候就需要我们手动进行配置了。问题描述&#xff1a;如果自动创建未能成功&#xff0c;不用担心&#xff0c;您要做的只是将数据库信息填入配置文件…

thinkphp使用echarts_Thinkphp 与Echarts-php 使用

这里推荐大家使用composer 依赖管理工具 导入Echarts-php库{"name": "hisune/echarts-php","version": "1.0.10","version_normalized": "1.0.10.0","source": {"type": "git",&qu…

创建文件夹 java_java怎么建文件夹

Java文件类以抽象的方式代表文件名和目录路径名。该类主要用于文件和目录的创建、文件的查找和文件的删除等。File对象代表磁盘中实际存在的文件和目录。下面我们来看一下java中创建文件夹的方法&#xff1a;示例&#xff1a;package com.zz;import java.io.File;import java.i…

【Gym - 101986F】Pizza Delivery(Dijkstra最短路,建图方式,反向建图,Tarjan求桥,图论模板)

题干&#xff1a; 题目大意&#xff1a; 一个有向图&#xff0c;编号1~n的n个点&#xff0c;m条边&#xff0c;规定1为起点&#xff0c;2为终点&#xff0c;问对于每一条边&#xff0c;反转它的方向&#xff0c;最短路会不会发生改变&#xff0c;如果变短了&#xff0c;输出HA…

【CF#505B】Mr. Kitayuta's Colorful Graph (并查集或Floyd或BFS)

题干&#xff1a; Mr. Kitayuta has just bought an undirected graph consisting of n vertices and m edges. The vertices of the graph are numbered from 1 to n. Each edge, namely edge i, has a color ci, connecting vertex ai and bi. Mr. Kitayuta wants you to p…

java data jpa_Spring Data JPA(一)简介

Spring Data JPA介绍可以理解为JPA规范的再次封装抽象&#xff0c;底层还是使用了Hibernate的JPA技术实现&#xff0c;引用JPQL(Java Persistence Query Language)查询语言&#xff0c;属于Spring整个生态体系的一部分。随着Spring Boot和Spring Cloud在市场上的流行&#xff0…

【CodeForces - 438D】The Child and Sequence(线段树区间取模操作)

题干&#xff1a; At the childrens day, the child came to Pickss house, and messed his house up. Picks was angry at him. A lot of important things were lost, in particular the favorite sequence of Picks. Fortunately, Picks remembers how to repair the sequ…

java 自定义xml_6.1 如何在spring中自定义xml标签

dubbo自定义了很多xml标签&#xff0c;例如&#xff0c;那么这些自定义标签是怎么与spring结合起来的呢&#xff1f;我们先看一个简单的例子。一 编写模型类1 packagecom.hulk.testdubbo.model;23 public classHero {4 privateString name;5 private intage;67 publicString ge…

java 模块设计模式_Java9模块化学习笔记二之模块设计模式

模块设计的原则:1、防止出现编译时循环依赖(主要是编译器不支持)&#xff0c;但运行时是允许循环依赖的&#xff0c;比如GUI应用2、明确模块的边界几种模块设计:API模块&#xff0c;聚合模块(比如java.base)可选依赖两种方式:1、可选的编译时依赖(类似于maven的provided scope)…

java 手写签名_Android 自定义View手写签名并保存图片

GIF压缩有问题&#xff0c;运行很顺滑&#xff01;&#xff01;&#xff01;1.自定义View——支持设置画笔颜色&#xff0c;画笔宽度&#xff0c;画板颜色&#xff0c;清除画板&#xff0c;检查是否有签名&#xff0c;保存画板图片(复制粘贴可直接使用)/*** Created by YyyyQ o…