题意:给定一个树形的机器结构,安装服务器,每台服务器恰好跟一台服务器相邻,问最少装几台服务器。
首先DFS把树建立起来,然后动规求解,注意设置无穷大inf后累加要防止超int范围。
1 #define _CRT_SECURE_NO_WARNINGS 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <cmath> 6 #include <vector> 7 #include <cstdlib> 8 #include <algorithm> 9 using namespace std; 10 11 const int maxn = 10240, inf = (1<<27); 12 int n, vis[maxn], dp[maxn][3]; 13 vector<int> G[maxn], sons[maxn]; 14 15 void DFS(const int u){ 16 for (unsigned i = 0; i != G[u].size(); ++i) if(!vis[G[u][i]]) { 17 sons[u].push_back(G[u][i]); 18 vis[G[u][i]] = true; 19 DFS(G[u][i]); 20 } 21 } 22 int solve(const int u, const int k){ 23 if (dp[u][k] != -1) return dp[u][k]; 24 int & ans = dp[u][k]; 25 if (k == 0) ans = 1; if (k == 1) ans = 0; if (k == 2) ans = inf; 26 for (unsigned i = 0; i != sons[u].size(); ++i){ 27 int v = sons[u][i]; 28 if (k == 0) ans += min(solve(v, 0), solve(v, 1)); 29 if (k == 1) ans += solve(v, 2); 30 if (k == 2) ans = min(ans, solve(u, 1) - solve(v, 2) + solve(v, 0)); 31 if (ans > inf) ans = inf; 32 } 33 return ans; 34 } 35 36 int main(){ 37 //freopen("in.txt", "r", stdin); 38 while (cin >> n){ 39 memset(G, 0, sizeof(G)); memset(sons, 0, sizeof(sons)); 40 memset(vis, 0, sizeof(vis)); memset(dp, -1, sizeof(dp)); 41 for (int i = 1; i < n; ++i){ 42 int x, y; cin >> x >> y; 43 G[x].push_back(y); G[y].push_back(x); 44 } 45 vis[1] = true; DFS(1); 46 cout << min(solve(1, 0), solve(1, 2)) << endl; 47 cin >> n; if (n == -1) return 0; 48 } 49 return 0; 50 }