1. 程式人生 > 實用技巧 >C Cover the Tree(選鏈覆蓋樹)

C Cover the Tree(選鏈覆蓋樹)

題: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;
vector
<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){ return
dfn[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 */
View Code