题意:
在山上一共有N个站点需要检查,检查员从山顶出发去各个站点进行检查,各个站点间有且仅有一条通路,检查员下山前往站点时比较轻松,而上山时却需要额外的时间,问最后检查员检查完所有站点时所需要的额外时间最少是多少。
题解:
dp[u][2],表示以u为节点的子树,0表示回来,1表示不会来。
#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<math.h> #include<stdio.h> #include<algorithm> #include<string.h> #include<vector> #include<queue> #include<map> #include<set> #define B(x) (1<<(x)) using namespace std; typedef long long ll; void cmax(int& a,int b){ if(b>a)a=b; } void cmin(int& a,int b){ if(b<a)a=b; } void cmax(ll& a,ll b){ if(b>a)a=b; } void cmin(ll& a,ll b){ if(b<a)a=b; } void add(int& a,int b,int mod){ a=(a+b)%mod; } void add(ll& a,ll b,ll mod){ a=(a+b)%mod; } const int oo=0x3f3f3f3f; const int MOD=1000000007; const double eps = 1e-8; const int maxn = 100005; int dp[maxn][2]; struct EDGE{ int v, w, next; }E[maxn]; int head[maxn], tol; void Init(){ memset(head, -1, sizeof head); tol = 0; } void add_edge(int u, int v, int w){ E[tol].v = v; E[tol].w = w; E[tol].next = head[u]; head[u] = tol++; } void tree_dp(int u){ dp[u][0] = oo; dp[u][1] = 0; int f = 0; for(int i = head[u]; i !=-1; i = E[i].next){ int v = E[i].v; tree_dp(v); dp[u][1] += dp[v][1] + E[i].w; f = 1; } for(int i = head[u]; i !=-1; i = E[i].next){ int v = E[i].v; cmin(dp[u][0], dp[u][1] - dp[v][1] - E[i].w + dp[v][0]); } if(!f) dp[u][0] = dp[u][1] = 0; } int main(){ int n,u,v,z; while(scanf("%d", &n) != EOF){ Init(); for(int i = 1; i <= n-1; i++){ scanf("%d %d %d", &u, &v, &z); add_edge(u, v, z); } tree_dp(1); printf("%d\n", dp[1][0]); } return 0; }