HDU 4714 Tree2cycle(樹形dp)
阿新 • • 發佈:2018-12-14
題解:
根據題目,我們可以知道只要求不是根的點所連點子鏈個數-1再加上根所連的子鏈個數-2為刪條的條數,就是可以這個樹可以分成多少條鏈,所刪條數*2+1就是答案了。
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <string> #include <vector> #include <bitset> #include <stack> #include <cmath> #include <deque> #include <queue> #include <list> #include <set> #include <map> #pragma comment(linker, "/STACK:1024000000,1024000000") #define line printf("---------------------------\n") #define mem(a, b) memset(a, b, sizeof(a)) #define pi acos(-1) using namespace std; typedef long long ll; const double eps = 1e-9; const int inf = 0x3f3f3f3f; const int mod = 1e9 + 7; const int maxn = 1000000 + 10; int du[maxn], head[maxn], ans, s, cnt; struct Edge{ int v, next; Edge(){}; Edge(int v, int next):v(v), next(next){}; }edge[maxn*2]; int dfs(int u, int father) { int sum = 0; for(int i = head[u]; ~i; i = edge[i].next){ int v = edge[i].v; if(v != father){ sum += dfs(v, u); } } if(sum >= 2){ if(s == u){ ans += sum-2; }else{ ans += sum-1; } return 0; }else{ return 1; } } void init(int n){ ans = cnt = 0; for(int i = 0; i <= n; i++){ head[i] = -1; du[i] = 0; } } void InsertEdge(int u, int v){ edge[cnt] = Edge(v, head[u]); head[u] = cnt++; } int main(){ int t; scanf("%d", &t); while(t--){ int n; scanf("%d", &n); init(n); for(int i = 0; i < n-1; i++){ int u, v; scanf("%d %d", &u, &v); du[u]++; du[v]++; InsertEdge(u, v); InsertEdge(v, u); } for(int i = 1; i <= n; i++){ if(du[i] == 1){ s = i; break; } } dfs(s, -1); printf("%d\n", ans*2+1); } }