#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<assert.h>
#include<vector>
#include<list>
#include<map>
#include<set>
#include<sstream>
#include<stack>
#include<queue>
#include<string>
#include<bitset>
#include<algorithm>
#pragma warning(disable:4996)
#define me(s) memset(s,0,sizeof(s))
#define _for(i,a,b) for(int i=(a);i<(b);++i)
#define _rep(i,a,b) for(int i=(a);i<=(b);++i)
using namespace std;
const int maxn = 10000 + 5;
const int INF = 1000000000;
vector<int> G[maxn], vertices;
int p[maxn], d[maxn][3];
void dfs(int u, int fa) {
vertices.push_back(u);
p[u] = fa;
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i];
if (v != fa) dfs(v, u);
}
}
int main() {
int n;
while (scanf("%d", &n) == 1) {
for (int i = 0; i < n; i++) G[i].clear();
for (int i = 0; i < n - 1; i++) {
int u, v;
scanf("%d%d", &u, &v); u--; v--;
G[u].push_back(v);
G[v].push_back(u);
}
vertices.clear();
dfs(0, -1); //无根树转为有根树,vertices其实存储的是对有根树先序遍历的结果
//状态分类: d(u,0) u是服务器,则子节点可以是服务器也可以不是,父节点也一样
//d(u,1) u不是服务器,而u的父亲是服务器,那么u不能再跟别的服务器相连,因此u的所有子节点都不是服务器
//d(u,2) u和u的父亲都不是服务器,那么u只能跟u的某一个子节点相连,也就是子节点中有且只有一个服务器
//状态转移方程 d(u,0)=sum{min(d(v,0),d(v,1))|v是u的子节点}
//d(u,1)=sum{d(v,2)|v是u的子节点}
//d(u,2)={min(d(u,1)-d(v,2)+d(v,0))|v是u的子节点
//很显然所有的节点都依赖于它的子节点的信息,所以采用自底向下的方法计算
//当然也可以采用递归的写法
//非递归写法
for (int i = vertices.size() - 1; i >= 0; i--) { //因为先序遍历,所以直接逆着算,一旦算到不是叶子的节点,它的所有子节点的信息也已经计算完了
int u = vertices[i];
d[u][0] = 1; d[u][1] = 0; //是不是服务器,先把自己加上
for (int j = 0; j < G[u].size(); j++) {
int v = G[u][j];
if (v == p[u]) continue; //只要子节点
d[u][0] += min(d[v][0], d[v][1]);
d[u][1] += d[v][2];
if (d[u][0] > INF) d[u][0] = INF; //防止爆int
if (d[u][1] > INF) d[u][1] = INF;
}
d[u][2] = INF;
//对于叶节点来说,它或者它的父节点必须有一个是服务器,所以它的d(u,2)是不存在的,
//所以这里初始化赋值为inf,从而后面算的时候取优的过程中会被抛弃
for (int j = 0; j < G[u].size(); j++) {
int v = G[u][j];
if (v == p[u]) continue;
d[u][2] = min(d[u][2], d[u][1] - d[v][2] + d[v][0]);
}
}
printf("%d\n", min(d[0][0], d[0][2]));
scanf("%d", &n);
}
}
Perfect Service UVA - 1218 树上的动态规划
猜你喜欢
转载自blog.csdn.net/qq_41776911/article/details/82772688
今日推荐
周排行