1. 程式人生 > >HDU 4714 Tree2cycle

HDU 4714 Tree2cycle

題目連結

題意

給一個圖,定義環為有n個結點,n條邊的圖。在圖中每刪和每加一條邊需要花費,求用最少的花費將圖變成環。

思路

思路比較難想到:看了題解才知道的。
對於非根結點,假設其後代分支數為f,需要先將結點與其父親斷開,然後斷開f-2個分支,將斷開的分支再連成一條鏈,共需要花費1+2*(f-2),在加上與上一條鏈的連結,總共需要2+2*(f-2) = 2*(f-1)
根結點沒有父親同理需要2(f-2)花費
連成一條鏈後,需要首尾相連再花費1

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring> #include<vector> #include<string> #include<queue> #include<stack> #include<set> #include<map> #define ll long long using namespace std; const int INF = ( 2e9 ) + 2; const ll maxn = 1e6+100; struct edge { int v,Next; }e[maxn*2]; int head[maxn]; int
tot,ans; bool mark[maxn]; void add(int u,int v) { e[tot].v=v; e[tot].Next=head[u]; head[u]=tot++; } void init() { memset(head,-1,sizeof(head)); tot=ans=0; } int dfs(int u,int fa) { int f=0; for(int i=head[u];i!=-1;i=e[i].Next) { int v=e[i].v; if(v==fa)continue
; f+=dfs(v,u); } if(f>1) { if(fa==-1)ans=ans+f-2; else ans=ans+f-1; return 0; } else return 1; } int main() { int T,n,u,v; scanf("%d",&T); while(T--) { init(); scanf("%d",&n); for(int i=0;i<n-1;i++) { scanf("%d%d",&u,&v); add(u,v); add(v,u); } dfs(1,-1); ans=ans*2+1; printf("%d\n",ans); } }