*【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,一经查实,立即删除!

相关文章

测试jdbc连mysql数据库_java连接mysql数据库及测试是否连接成功的方法

本文实例讲述了java连接mysql数据库及测试是否连接成功的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;package com.test.tool;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import…

mysql配置日志老化配置_mysql配置-日志大小限制和自动删除

线上的项目磁盘消耗问题, 发现和MySQL日志有关系.需要处理的问题如何限制大小 不让日志无限膨胀?配置日志不留?删除的方式和直接删除会对服务有什么影响?解决方式限制大小, 保留最近一段时间日志.set global expire_logs_days7; # 命令行进入MySQL中, 临时设置保留最近7天日…

【HDU - 5091】Beam Cannon(线段树,扫描线)

题干&#xff1a; Recently, the γ galaxies broke out Star Wars. Each planet is warring for resources. In the Star Wars, Planet X is under attack by other planets. Now, a large wave of enemy spaceships is approaching. There is a very large Beam Cannon on t…

mysql的传播特性_spring事务传播特性和mysql事务隔离级别

spring事务的传播特性--7种REQUIRED支持当前事务&#xff0c;如果没有事务会创建一个新的事务SUPPORTS支持当前事务&#xff0c;如果没有事务的话以非事务方式执行MANDATORY(强制性)支持当前事务&#xff0c;如果没有事务抛出异常REQUIRES_NEW创建一个新的事物并挂起当前事务NO…

【 HDU - 5093】Battle ships(匈牙利算法,二分图匹配)

题干&#xff1a; Dear contestant, now you are an excellent navy commander, who is responsible of a tough mission currently. Your fleet unfortunately encountered an enemy fleet near the South Pole where the geographical conditions are negative for both si…

【HDU - 5090】Game with Pearls (匈牙利算法,二分图匹配)

题干&#xff1a; Tom and Jerry are playing a game with tubes and pearls. The rule of the game is: 1) Tom and Jerry come up together with a number K. 2) Tom provides N tubes. Within each tube, there are several pearls. The number of pearls in each tube i…

qt同时连接oracle和mysql_QT连接Oracle和Mysql的详细步骤,已成功~!

近几天一直在整QT的数据库连接这一块。因为QT是开源的&#xff0c;所以涉及的连接Oracle及Mysql的驱动都必须自己编译生成。通过不断的测试、调试&#xff0c;终于把QT连接Oracle和Mysql的驱动编译生成好了。QT环境&#xff1a;Qt 4.6.0打开Qt Command Prompt&#xff0c;开始菜…

【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…

一台linux上运行多个mysql_linux下同时运行多个mysql

来自网络&#xff0c;感谢开源&#xff0c;感谢分享通过rpm安装mysql&#xff0c;测试版本5.1.481、在linux下通过:#useradd multi -g mysql -s /sbin/nologin添加一个multi用户&#xff0c;并加入到mysql组#passwd multi给multi用户添加密码&#xff0c;这里设置的密码为multi…

【SPOJ - QTREE2】Query on a tree II(LCA,倍增)

题干&#xff1a; You are given a tree (an undirected acyclic connected graph) with N nodes, and edges numbered 1, 2, 3...N-1. Each edge has an integer value assigned to it, representing its length. We will ask you to perfrom some instructions of the foll…

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

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

【蓝桥杯 - 试题】立方尾不变(tricks,快速取出一个数字的后n位)

题干&#xff1a; 有些数字的立方的末尾正好是该数字本身。 比如&#xff1a;1,4,5,6,9,24,25,.... 请你计算一下&#xff0c;在10000以内的数字中&#xff08;指该数字&#xff0c;并非它立方后的数值&#xff09;&#xff0c;符合这个特征的正整数一共有多少个。 请提交该…

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;然后点击上方的“编辑用户”按…

【POJ - 2486】Apple Tree (树形背包,dp)

题干&#xff1a; Wshxzt is a lovely girl. She likes apple very much. One day HX takes her to an apple tree. There are N nodes in the tree. Each node has an amount of apples. Wshxzt starts her happy trip at one node. She can eat up all the apples in the no…

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;要攻克这些…

mysql判断域为空_MySQL EXPLAIN 字段说明

id查询或关联查询的顺序。如果没有子查询且只有一个查询&#xff0c;则为一个常数 1&#xff0c;表示第一步&#xff1b;如果有子查询&#xff0c;则子查询为 1&#xff0c;父查询为 2&#xff1b;相同的 id 查询顺序为自上而下&#xff1b;如果有子查询&#xff0c;不同 id 值…

【CodeForces - 618A】Slime Combining(二进制,思维)

题干&#xff1a; Your friend recently gave you some slimes for your birthday. You have n slimes all initially with value 1. You are going to play a game with these slimes. Initially, you put a single slime by itself in a row. Then, you will add the other…