17AHU排位赛2 E题(树上最大匹配,树形DP)
生活随笔
收集整理的這篇文章主要介紹了
17AHU排位赛2 E题(树上最大匹配,树形DP)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
problem
有一個n個節點n-1條邊組成的樹。
每個點看成一個人,連接u和v的邊看成是“中意關系”,即u和v兩個人都想和對方組隊。每個人希望組隊的對象有可能有多個。
一支隊伍由且僅由兩個人組成,并且如果u和v組隊了,那么u、v將不能和其他人再組成一支隊。
現在問你,這n個人最多能組成多少支隊伍。(允許某些人組不了隊)
Input
第一行輸入一個整數n,m(1<=n<=200000)
接下來n-1行,每行兩個整數u,v,表示u和v兩個人都想和對方組隊。
數據保證是一個合法的樹。
Output
輸出一個整數,表示最多能組成多少支隊伍。
Input
5
1 2
1 3
2 4
4 5
Output
2
Limitation
1s 256MB
Hint
一種可行的組隊方案:
1與3組隊
4與5組隊
最多組成2支隊
思路
基本的樹形DP
dp[rt][0]表示rt這個點不與任何一個兒子連邊,以k為根的子樹的最大匹配
dp[rt][1]表示rt這個點與某一個兒子連邊,以k為根的子樹的最大匹配
核心代碼
void dfs(int rt,int f) {int mi=n;if(G[rt].size()==1&&G[rt][0]==f){return ;}for(int i=0;i<G[rt].size();++i){int tt=G[rt][i];if(tt==f) continue;dfs(tt,rt);dp[rt][0]+=dp[tt][1];dp[rt][1]+=dp[tt][1];if(dp[tt][1]-dp[tt][0]<mi) mi=dp[tt][1]-dp[tt][0];}dp[rt][1]=dp[rt][1]-mi+1; }代碼示例
#include<bits/stdc++.h> using namespace std; const int maxn=200010;int n;vector<int> G[maxn];int dp[maxn][2];void dfs(int rt,int f) {int mi=n;if(G[rt].size()==1&&G[rt][0]==f){return ;}for(int i=0;i<G[rt].size();++i){int tt=G[rt][i];if(tt==f) continue;dfs(tt,rt);dp[rt][0]+=dp[tt][1];dp[rt][1]+=dp[tt][1];if(dp[tt][1]-dp[tt][0]<mi) mi=dp[tt][1]-dp[tt][0];}dp[rt][1]=dp[rt][1]-mi+1; }int main() {ios::sync_with_stdio(false);cin>>n;int u,v;for(int i=1;i<n;++i){cin>>u>>v;G[u].push_back(v);G[v].push_back(u);}dfs(1,0);cout<<max(dp[1][0],dp[1][1])<<endl;return 0; }總結
以上是生活随笔為你收集整理的17AHU排位赛2 E题(树上最大匹配,树形DP)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mindjet mindmanager2
- 下一篇: GitHub提交出错处理【2022年】