C Cover the Tree(選鏈覆蓋樹)
阿新 • • 發佈:2020-07-14
題:https://ac.nowcoder.com/acm/contest/5667/C
題意:選最少數量的“鏈”來覆蓋整顆樹,使樹的每條邊都至少被覆蓋一次
分析:關鍵是理解證明過程:
:
#include<bits/stdc++.h> using namespace std; #define pb push_back #define MP make_pair typedef long long ll; const int mod=1e9+7; const int M=2e5+5; const int inf=0x3f3f3f3f; const ll INF=1e18; vectorView Code<int>g[M]; int a[M],du[M],dfn[M],cnt; void dfs(int u,int fa){ dfn[u]=++cnt; for(auto v:g[u]) if(v!=fa) dfs(v,u); } int main(){ int n; scanf("%d",&n); for(int i=1;i<n;i++){ int u,v; scanf("%d%d",&u,&v); g[u].pb(v); g[v].pb(u); du[u]++,du[v]++; } if(n==1) return puts("0"),0; else if(n==2) return printf("1\n%1 2"),0; int tot=0,rt=1; for(int i=1;i<=n;i++) if(du[i]==1) a[tot++]=i; else rt=i; dfs(rt,0); sort(a,a+tot,[&](int x,int y){ returndfn[x]<dfn[y]; }); int tmp=tot/2; if(tot&1){ printf("%d\n",tmp+1); printf("%d %d\n",rt,a[tot-1]); } else printf("%d\n",tmp); for(int i=0;i<tmp;i++) printf("%d %d\n",a[i],a[i+tmp]); return 0; } /** 8 1 2 2 3 3 4 3 5 1 7 7 6 7 8 */