8102年,Normalgod在GLaDOS的帮助下,研制出了传送枪。但GLaDOS想把传送枪据为己有,因而把Normalgod扔进了一间实验室。这间实验室是一棵有n个节点的树。如今Normalgod在一号节点,出口也在一号节点,但为了打开它,必须通过每个节点按下每一个节点的开关,出口才能打开。GLaDOS为了杀死Normalgod,开始在实验室里释放毒气,所以Normalgod必须尽快逃出这间实验室。 固然,Normalgod手中的传送枪是可使用的。传送枪能够发射出两个颜色不一样的传送门。Normalgod能够从其中一个传送到另外一个。尽管传送枪能够在视野范围内的任何一个通过特殊处理的表面打开一扇传送门,但这间实验室的设计使得Normalgod只能在他所处的房间内打开一个传送门。 在已经存在了一个同颜色的传送门时,打开新的传送门会使与它同颜色的旧门消失。传送和打开传送门所需时间为0。 显然,利用传送枪会让Normalgod更快解决谜题,可Normalgod死在了按下最后一个按钮的路上。尽管如此,GLaDOS仍是很想知道到底Normalgod最快能用多久逃出去,这对她的实验室设计方法论有重要的指导做用。做为GLaDOS的算法模块,你要完成这个任务。本题时限为2000ms
第一行一个整数n。以后n-1行,每行三个整数ui,vi,ai ,表示有一条从ui 连向vi ,花费时间为ai 的通道。php
一行一个数T,表示最小的脱逃时间。ios
5
1 2 2
2 3 3
2 4 5
1 5 1算法
13ide
1–> open1–> 5–> open2–> use(1)–> 2–> 3–> open2–> use(1)–> 2–> 4–> open2–> use(1)–> exitui
题意:给定n个结点的树,每条边权wi,能够进行传送门操做,求通过每一个结点并最终回到根节点的最短路径长度。spa
设dp[i][0/1]
0表示在i点及i点儿子设传送门所能获得的最大总和
1 表示不在i点及i点儿子设传送门所能获得的最大总和设计
首先,对于dp[i][1]的状况,必定存在i点的祖先中有传送门,这样才能使结果更优。因此对于他的每个儿子都能跳回到他的祖先。但实际上只有使一个儿子跳回祖先时,才能保证fa->i的边通过两次。
不然转化为dp[i][0]的状况。则咱们要使选的儿子最优。
dp[i][1]=max(dp[vi][1]+wi);
其次,对于dp[i][0]的状况,在每一个儿子中设立传送门并不会影响到其余儿子,由于总能从儿子回到i时再在i重设传送门。因此咱们就取每一个儿子设与不设的最优值之和。
dp[i][0]=Σmax(dp[vi][0],dp[vi][1]+wi);code
#include<iostream> #include<cstdio> #define ll long long using namespace std; const ll maxn=1e6+77; long long n,f[maxn][2],d[maxn],list[maxn],cnt; struct E { ll to,next,v; }e[maxn*2]; void add(ll u,ll v,ll val) { e[++cnt].to=v; e[cnt].next=list[u]; list[u]=cnt; e[cnt].v=val; } void dfs(ll u,ll fa) { for(ll i=list[u]; i; i=e[i].next) { ll v=e[i].to; if(v==fa) continue; dfs(v,u); d[u]=max(d[u],d[v]+e[i].v); f[u][0]+=f[v][0]+e[i].v*2; f[u][1]+=min(f[v][0]+e[i].v-d[v],f[v][1]+e[i].v*2); } } int main() { freopen("portal.in","r",stdin),freopen("portal.out","w",stdout); scanf("%lld",&n); for(ll i=1,x,y,z; i<=n-1; i++) scanf("%lld%lld%lld",&x,&y,&z),add(x,y,z),add(y,x,z); dfs(1,0); printf("%lld",f[1][1]); }