LiberOJ #6210. 「美团 CodeM 决赛」tree 树形DP
生活随笔
收集整理的這篇文章主要介紹了
LiberOJ #6210. 「美团 CodeM 决赛」tree 树形DP
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:點這里
題解:
需要證明,所求的路徑一定是全部權值都為1或者,路徑上權值至多有一個為2其余為1且權值2在路徑中央。
然后樹形DP
設定dp[i][0/1] 以1為根的情況下,以i 節點下子樹走分別全1和 走一次2和剩余全走1 的最長鏈
每遍歷一次子樹,統計一次答案
下面給出代碼
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define ls i<<1 #define rs ls | 1 #define mid ((ll+rr)>>1) #define pii pair<int,int> #define MP make_pair typedef long long LL; const long long INF = 1e18+1LL; const double pi = acos(-1.0); const int N = 5e5+10, M = 1e3+20,inf = 2e9; const LL mod = 1e9+7LL;int n,a[N],ans; int ans1,ans2; vector<int > G[N]; int dp[N][2]; void dfs(int u,int f) {if(a[u] == 1) dp[u][0] = 1;else if(a[u] == 2) dp[u][1] = 1;for(int i = 0; i < G[u].size(); ++i) {int to = G[u][i];if(to == f) continue;dfs(to,u);ans1 = max(ans1,dp[to][0] + dp[u][0]);ans2 = max(ans2,dp[u][0] + dp[to][1]);ans2 = max(ans2,dp[u][1] + dp[to][0]);if(a[u] > 2)continue;if(a[u] == 1) {dp[u][0] = max(dp[u][0],dp[to][0] + 1);dp[u][1] = max(dp[u][1],dp[to][1] + 1);}else {dp[u][1] = max(dp[u][1],dp[to][0] + 1);}} } int main(){scanf("%d",&n);for(int i = 1; i < n; ++i) {int x,y;scanf("%d%d",&x,&y);G[x].push_back(y);G[y].push_back(x);}int mi = inf;for(int i = 1; i <= n; ++i) {scanf("%d",&a[i]);mi = min(mi,a[i]);}ans = 0;dfs(1,0);if(mi >= 2) {printf("%d/1\n",mi);}else {if(2*ans1 > ans2) printf("1/%d\n",ans1);else if(ans2 % 2 == 0) printf("1/%d\n",ans2/2);else printf("2/%d\n",ans2);}return 0; }轉載于:https://www.cnblogs.com/zxhl/p/7295699.html
總結
以上是生活随笔為你收集整理的LiberOJ #6210. 「美团 CodeM 决赛」tree 树形DP的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 推荐一个妹子,播报汽车新闻
- 下一篇: EUI库 - EXML