树形DP之自驾旅行
来源:互联网 发布:长沙启航学校网络教育 编辑:程序博客网 时间:2024/04/29 10:50
hihocoder – 1035
题目链接:http://hihocoder.com/problemset/problem/1035
题目类型:树形DP
DP类编程题目的关键是找到转移方程,本题转移方程的设计如下:
dsf[i][j]表示遍历完所有子树之后,某一个节点所处的状态,共分5种情况:
dsf[fa][0]:人去人不回,含义是从该节点出发,每条路径都是人走,最终人不返回该节点,而是停留在某一课子树当中;
dsf[fa][1]:人去人回,含义是从该节点出发,每条路径都是人走,最终人返回该节点;
dsf[fa][2]:人车去人车回,含义是从该节点出发,每条路径可以是人走,也可以驾车,但是最终要保证人车都处于该节点;
dsf[fa][3]:人车去人回,含义是从该节点出发,每条路径可以是人走也可以驾车,但是最终人处于该节点,车处于某颗子树当中;
dsf[fa][4]:人车都去,含义是从该节点出发,每条路径既可以人走,也可以乘车,最终人车都不在该节点,而是在某颗子树当中;
下面设计转移方程,w1(fa,son)、w2(fa,son)分别表示人走和乘车的代价:
1)dsf[fa][1] ,dsf[fa][2]:
dsf[fa][1] = ∑ dsf[son][1] + 2 w1(fa,son);
dsf[fa][2] = ∑ min(dsf[son][1] + 2 w1(fa,son) , dsf[fa][2] + 2 w2(fa,son));
2) dsf[fa][0]:
tmp = min( dsf[son[0] - w1(fa,son) - dsf[son][1]) ; tmp = min (tmp , 0)
dsf[fa][0] = dsf [fa][1] + tmp;
3)dsf[fa][3] :
t2 = min(2 w1(fa,son) + dsf[son][1] , 2 w2(fa,son) + dsf[son][2]);
t3 = 0 ; t2 = min (t3 , w1(fa,son) + w2(fa,son) + dsf[son] [3] - t2);
dsf[fa][3] = dsf[fa][2] + t2;
4)dsf[fa][4]分两种情况
- 走最后一棵树时还有车:
tmp1 = min(w1(fa,son) + dsf[son][0],w2(fs,son) + dsf[son][4]),
tmp2 = min (tmp1 - t2);
tmp3 = min(0,tmp3);
dsf[fa][4] = dsf[fa][2] + tmp3; - 走最后一棵树时没车了:
这种情况表示,在走最后一棵树之前走某一课子树时的情况是(w2(fa,son) + w1(fa,son) + dsf[son][3]),
此时最后一棵树的决策是:
(w1(fa,son) + dsf[son][0]);
令 ff1 = w2(fa,son) + w1(fa,son) + dsf[son][3] - t2;
ff2 = w1(fa,son) + dsf[son][0] - t2;
求得ff1 + ff2 的最小值,则dsf[fa][4] = dsf[fa][2] + ff1 + ff2;
C代码实现(手打,若有错误还请谅解):
#include<stdio.h>#include<stdlib.h>//定义最大节点个数 MAX_NUM#define MAX_NUM (1000000001)#define INF (1 << (30))//定义结点类型typedef struct node{ int c0,c1,v; struct node * next;}node;//静态开辟节点存储空间node buf[2 * MAX_NUM];int buffsize = 0; // sp//定义节点数组node * head[MAX_NUM] = {NULL};//定义关键结点标记数组bool vis[MAX_NUM] ={false};//定义DP辅助结构int dp[MAX_NUM][5] = {0};//定义插入一条边的函数(将孩子、父亲节点插入孩子、父亲链表时,采用头插法)void insert(int u,int v,int c0,int c1){ //首先得到一个结点的空间指针 node * p = buf + buffsize ++; { p -> c0 = c0; p -> c1 = c1; p -> v = v; p -> next = head[u]; } { p = buf + buffsize ++; p ->c0 = c0; p -> c1 = c1; p -> v = u; p -> next = head[v]; head[v] = p; }}//树形DP处理函数void dsf(int u,int fa){ node * p = head[u]; for(;p != NULL; p = p -> next) { int v = p -> v; if(v == fa) continue; dsf(v,u); vis[u] |= vis[v]; } if(vis[u] == true) { dp[u][0] = dp[u][1] = dp[u][2] \ = dp[u][3] = dp[u][4] =0; p = head[u] ; //求dp[u][1]; for(;p;p = p ->next) { int v = p -> v; if(v == fa) continue; if(vis(v)) { tmp2 = min(2 * p -> c0 + dp[v][1], 2 * p -> c1 + dp[v][2]); dp[u][1] += dp[v][1] + (2 * p -> c0); dp[u][2] += tmp2; tmp0 = min(tmp0,dp[v][0] - dp[v][1] - p -> c0); tmp3 = min(tmp3,p -> c1 + p -> c0 +dp[v][3] - tmp2); tmp41 = min(tmp41,min(p -> c0 + dp[v][0], p -> c1 + dp[v][4]) - tmp2); ff1 = p -> c0 + p -> c1 + dp[v][3] - tmp2; ff2 = p -> c0 + dp[v][0] - tmp2; if(ff1 < t1) { match1 = v; t2 = t1; t1 = ff1; } else t2 = min(ff1,t1); if(ff2 < f1) { match2 = v; f2 = f1; f1 = ff2; } else f2 = min(f1,ff2); } } }}
- 树形DP之自驾旅行
- hihoCoder 1035 自驾旅行 树形DP
- hihoCoder 1035 自驾旅行 树形dp
- hihocoder #1035 : 自驾旅行 III 树形DP
- BZOJ(本校) 3044 旅行 - 树形dp&基环树
- hdu4714之树形DP
- hdu1561之树形dp
- poj1155之树形DP
- hdu1011之树形dp
- hdu1520之树形dp
- 【树dp+状态机背包】 自驾旅行III 找最小权路径
- 树形DP练习 转自ZEROCLOCK
- 树形dp之删边
- 陕西省集训之树形dp
- 树形DP之王 balabalabala
- 树形dp 生命之树
- hihocoder #1035 : 自驾旅行 III
- bzoj 1917: [Ctsc2010]星际旅行 树形dp解决树上网络流
- ubuntu 防火墙使用
- #Codeforces 381 [div2] D. Alyona and a tree 【树链剖分 + 优先队列】
- Android UI-聊天界面
- tools:context=".MainActivity的作用
- Android Image开源框架之ImageLoader(一)
- 树形DP之自驾旅行
- 【第十三周项目3---Dijkstra算法验证】
- 【Hadoop】Spark2.0.2在Hadoop2.7.3上的安装
- 第十二周 项目4-利用遍历思想求解图问题(3)(4)
- 第13周项目5-拓扑排序算法验证
- maven3—自动创建目录骨架,maven中的坐标和仓库
- Android 利用 EasyDarwin 进行视频直播
- Visual Studio2013统计代码行数
- 关于UI的开发是使用代码还是Xib