Cover the Tree(2020多校第二场C)
生活随笔
收集整理的這篇文章主要介紹了
Cover the Tree(2020多校第二场C)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Cover the Tree
文章目錄
- 題意:
- 題解:
- 代碼
題意:
一個無向樹,選擇最少數量的鏈子,能將樹上所有邊覆蓋,答案不唯一
(1≤n≤2×105)
鏈子就是兩點之間的邊
看看樣例
輸入
輸出
2 2 3 4 5一種情況如圖所示:
所有邊被覆蓋的鏈子有:
鏈子2->3:覆蓋了邊1-2,1-3
鏈子4->5:覆蓋了邊4-2,2-5
題解:
上述文字看不懂也沒關系,我也不大懂,我結合題解談談我的認識
所用知識:
dfs序講解
題目要求我們找鏈,鏈有兩個端點,其實說白了就是在樹上兩兩找點,讓他們匹配,要覆蓋所有邊
如果有x個葉子節點,那我們最少的子鏈也要是(x/2)向上取整(不然不能覆蓋所有與葉子節點相連的邊)
我們讓根左子樹的葉節點和根右子樹的葉節點一一配對,如果葉節點是奇數個的話,再任意找一個節點與之配對即可。
如果任意葉子節點匹配
如圖
很容易造成遺漏,比如1——3這條邊就沒有,
所以我們要按照每種特定的順序來實現不遺漏,而且所用鏈不多
我們用dfs序對每個點進行編號,讓x與x+(n/2)交叉匹配,這樣就不重復了,
最后跑一遍dfs序,記錄一下葉子節點出現的位置進行輸出
代碼
#include<bits/stdc++.h> #include<vector> using namespace std; const int maxn=2e5+7; vector<int> vec[maxn]; vector<int>sum; void dfs(int x,int pre) { if(vec[x].size()==1)sum.push_back(x);//將每個葉子節點存放入 for(auto i:vec[x]){if(i==pre)continue;dfs(i,x);} } int main() {int n;cin>>n;for(int i=1;i<n;i++){int u,v;cin>>u>>v;vec[u].push_back(v);vec[v].push_back(u);}int root=1;while(vec[root].size()==1)root++;//我們要選的根節點不能只連接一個邊dfs(root,-1);//dfs序 int size=sum.size();int ant=(size+1)/2;//另一個點的編號 cout<<ant<<endl;if(size&1)sum.push_back(root);//如果奇數個點,則將根和多的葉子節點匹配 for(int i=0;i<ant;i++){cout<<sum[i]<<" "<<sum[i+ant]<<endl;}return 0; }總結
以上是生活随笔為你收集整理的Cover the Tree(2020多校第二场C)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网站怎么无法访问(网站怎么无法访问了)
- 下一篇: 牛客网【每日一题】7月21日题目精讲—区