結點選擇ios
/* 首先這道題輸入的邊的兩端的結點不是上一行的結點的權值,而是 結點的序號,其次,這道題並無說這個樹是二叉樹而且也沒有說邊左 邊的結點就是父親結點,右邊的結點就是孩子結點,因此這道題樹的存 儲用無向圖來存儲。 關於算法就是樹形規劃:從葉子結點往上到根節點進行動態規劃, 利用dfs來實現這個葉子節點到根節點。 動態規劃的狀態呢分爲:對根節點爲序號爲a的子樹來講呢, dp[a][0]就是不選當前結點所能選出的結點最大值。 dp[a][1]是選當前結點的能選出的最大值。 關於這個dp的初始化,將全部結點視爲葉子結點,根據狀態呢,顯然dp[a][0]=0,dp[a][1]=這個a點的權值。 動態轉移方程見下面程序代碼dfs處。 */ #include<iostream> #include<vector> using namespace std; vector<vector<int> > v; int dp[100005][2]={0}; void dfs(int a, int pre){ for(int i=0; i<v[a].size(); i++){ int t=v[a][i]; if(t!=pre){ dfs(t, a); dp[a][0]+=max(dp[t][0], dp[t][1]); dp[a][1]+=dp[t][0]; } } } int main(){ int n, a, b; cin>>n; v.resize(n+1); for(int i=1; i<=n; i++) scanf("%d", &dp[i][1]); for(int i=0; i<n-1; i++){ scanf("%d%d", &a, &b); v[a].push_back(b); v[b].push_back(a); } dfs(1, 0); cout<<max(dp[1][0], dp[1][1])<<endl; return 0; }