【题解】UVA1218 Perfect Service

UVA1218:https://www.luogu.org/problemnew/show/UVA1218
刷紫书DP题ing

思路

参考lrj紫书 不喜勿喷

  1. d(u,0):u是服务器,孩子是不是服务器均可
  2. d(u,1):u不是服务器,u的父亲是服务器,u的孩子不能是服务器
  3. d(u,2):u不是服务器且u的父亲不是服务器,u的孩子必须有且仅有一个是服务器。

前两个状态方程好写
那么d(u,2)呢?
d(u,2)就会等于 他儿子全都不是 减去某个不是 再加上某个是 这是这道树形DP的难点

因此 状态方程:d(u,2) = Min(d(u,1)-d(v,2)+d(v,0)) |v是u的孩子

详细解释见代码~

代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
using namespace std;
#define maxn 10010
vector<int> sons[maxn];
int dp[maxn][3];
int n;
void search(int u,int father)
{
   dp[u][0]=1;//本身算一个
   dp[u][1]=0;
   dp[u][2]=maxn;//要查找 先定义成最大
   for(int i=0;i<sons[u].size();i++)
   {
       if(sons[u][i]!=father)//如果不是父亲 就是儿子
       {
           search(sons[u][i],u);//递归查找
           dp[u][0]+=min(dp[sons[u][i]][0],dp[sons[u][i]][1]);//如果他是 儿子可以是或者不是
           dp[u][1]+=dp[sons[u][i]][2];//如果他不是 但他父亲是 儿子都不是
       }
   }
   for(int i=0;i<sons[u].size();i++)
   {
       if(sons[u][i]!=father)
       dp[u][2]=min(dp[u][1]-dp[sons[u][i]][2]+dp[sons[u][i]][0],dp[u][2]);
       //如果他不是 他父亲也不是 那么就是他儿子全都不是减去某个不是再加上某个是
   }
}
int main()
{
   while(scanf("%d",&n)==1)
   {
       int x,y;
       for(int i=1;i<n;i++)
       {
           scanf("%d%d",&x,&y);//存边
           sons[x].push_back(y);
           sons[y].push_back(x);
       }
       search(1,-1);
       printf("%d\n",min(dp[1][0],dp[1][2]));//答案在第一个是服务器
                                             //或者第一个不是但是儿子之一是
       scanf("%d",&x);//数据结束
       if(x==-1)
       break;
       for(int i=1;i<=n;i++)//初始化
       sons[i].clear();
       memset(dp,0,sizeof(dp));
   }
}

原文地址:https://www.cnblogs.com/BrokenString/p/9439934.html

时间: 2024-11-15 06:41:12

【题解】UVA1218 Perfect Service的相关文章

[UVA-1218] Perfect Service(树的最小支配集)

题目链接:https://vjudge.net/problem/UVA-1218 题目大意:给你一棵无向树,让你求树的最小支配集,但是有一个要求是除最小支配集外剩下的任何一个结点不能同时连接支配集中的两个元素 解题报告:采用树形dp,只需将第一种状态的状态转移方程修改为$dp[i][0] = 1+\sum_{ p[u]=i }min(dp[u][0],dp[u][2])$ AC代码: 1 #include<vector> 2 #include<cstdio> 3 #include&

UVa-1218 - Perfect Service

d[u][0][1]=sum{d[v][0]} d[u][1][1]=d[u][1][0]=sum{min(d[v][0],d[v][1])} d[u][0][0]=sum{d[v][0]}-d[min][0]+d[min][1]   (d[min][1]=min(d[v][1])) 调了很久.... 看到lrj是先dfs找好路径,再反方向沿着路径递推.O(n). 最近效率低下! 谁笑到最后谁笑得最好! 1 #include<cstdio> 2 #include<cstring>

uva1218 Perfect Service

题目大意: 有n(n≤10000)台机器形成树形结构.要求在其中一些机器上安装服务器,使得每台不是服务器的计算机恰好和一台服务器计算机相邻.求服务器的最少数量. /* 递归时分为3种情况 0表示,u为服务器,那么他的所有子节点可以为服务器也可以不为服务器 res+=min(dp[v][0],dp[v][1]); 1表示,u不为服务器,但是u的父节点为服务器,那么所有子节点都不能为服务器 res=sum(dp[v][2]); 2表示,u不为服务器,且u的父亲也不为服务器,那么u的子节点中只有一个为

UVA1218 Perfect Service(染色问题--树形DP)(好题,通法)

题意:一棵树,进行染色,每个没染色的节点恰好和一个染色的节点相连,求染色的节点最少的个数X(以下均以X代表子问题的解) 思路:树形DP,细化状态,从而对每个节点的每种状态互相递推 这里如何细化状态是难点,而且也是这类难题的共同问题 很容易知道每个节点i至少两个状态:dp[i][0]: i没染上色时以i的子树的X.dp[i][1]: i被染色以i为子树的X 但是仅仅这两个状态无法实现状态转移因为: dp[u][0]=sum(dp[v][0],dp[v][1])+1  (dp[u][0]可以找到状态

UVA - 1218 Perfect Service(树形dp)

题目链接:id=36043">UVA - 1218 Perfect Service 题意 有n台电脑.互相以无根树的方式连接,现要将当中一部分电脑作为server,且要求每台电脑必须连接且仅仅能连接一台server(不包含作为server的电脑).求最少须要多少台电脑作为server. 思路 典型的树形dp问题,那么我们来建立模型. d(u,0):u是server,孩子是不是server均可 d(u,1):u不是server,u的父亲是server,u的孩子不能是server d(u,2)

Perfect Service UVA - 1218(树形dp)

Perfect Service UVA - 1218 题意:安装服务器,使得不是服务器的计算机恰好和一台服务器计算机相连.问最少安多少服务器计算机. 之前一直不理解第三个转移方程,,今天再看竟然是错的!!可是却过了!! 下面的是改过的了. 1 #include <cstdio> 2 #include <bits/stdc++.h> 3 using namespace std; 4 const int maxn=10010; 5 int d[maxn][3]; 6 int in[ma

POJ 3398 / UVA 1218 Perfect Service 树形DP

树形DP Perfect Service Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 1378   Accepted: 668 Description A network is composed of N computers connected by N ? 1 communication links such that any two computers can be communicated via a uniqu

POJ 3398 Perfect Service(树形DP,最小支配集)

#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <set> #include <stack> #include <map> #define LL long

【POJ】3398 Perfect Service

1. 题目描述某树形网络由$n, n \in [1, 10^4]$台计算机组成.现从中选择一些计算机作为服务器,使得每当普通计算机恰好与一台服务器连接(并且不超过一台).求需要指定服务器的最少数量 2. 基本思路这显然是一个求最优解的问题,并且该网络拓扑结构为树形.因此,考虑树形DP.关键是考虑有哪些状态?不妨令(1) $dp[u][0]$表示$u$作为服务器,那么它的儿子结点可以是服务器或者普通机:(2) $dp[u][1]$表示$u$是普通计算机,但是$fa[u]$作为服务器,那么它的儿子结