思路:一棵树,叶子节点上有一个苹果,问CC从哪个非叶子节点出发获得两个苹果话的时间最少,速度one meter per second,给出两相连两点之间的距离。
这个就是树形dp;
dp[i][j]表示在第i号节点获取j个苹果的代价。
dp[u][2] = min(dp[u][2], dp[u][1] + dp[v][1] + val);
dp[u][1] = min(dp[u][1],dp[v][1]+val);
// #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <climits> using namespace std; // #define DEBUG #ifdef DEBUG #define debug(...) printf( __VA_ARGS__ ) #else #define debug(...) #endif #define CLR(x) memset(x, 0,sizeof x) #define MEM(x,y) memset(x, y,sizeof x) #define pk push_back template<class T> inline T Get_Max(const T&a,const T&b){return a < b?b:a;} template<class T> inline T Get_Min(const T&a,const T&b){return a < b?a:b;} typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> ii; const double eps = 1e-10; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int maxn = 10010; vector<ii> G[maxn]; int deg[maxn]; int dp[maxn][3]; int in[maxn]; int n; int Min; void Search(int u,int fa){ for (int i = 0;i < G[u].size();++i){ int v = G[u][i].first; int w = G[u][i].second; if (v==fa)continue; Search(v,u); // int ans = dp[u][1]; dp[u][2] = Get_Min(dp[u][2],dp[u][1]+dp[v][1]+w); dp[u][1] = Get_Min(dp[u][1],dp[v][1]+w); Min = Get_Min(Min, dp[u][2]); } } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); while(scanf("%d",&n) != EOF && n){ // memset(dp, INF,sizeof dp); for (int i = 1;i <= n;++i){ dp[i][1] = dp[i][2] = inf; } memset(in, 0,sizeof in); memset(deg, 0,sizeof deg); Min = INF; for (int i = 1;i <= n;++i) G[i].clear(); int root; int u, v, c; for (int i = 1;i <= n - 1;++i){ scanf("%d%d%d",&u,&v,&c); deg[u]++; deg[v]++; G[u].push_back(ii(v, c)); G[v].push_back(ii(u, c)); in[v] = 1; } for (int i = 1;i <= n;++i){ if (deg[i]==1) dp[i][1]=0; } for (int i = 1;i <= n;++i){ if (in[i]==0){ root = i; break; } } Search(root, -1); cout << Min << endl; } return 0; }