树形 DP hdu4714 Tree2cycle


好坑的题,如果不加栈就会re,加栈以后记得交c++

#pragma comment(linker, "/STACK:1024000000,1024000000")

树形dp

思路:

分析出构成环的最少步骤

其实就是找将分开一条一条线连接成环

从每个点开始分析

如果一个点它的度数是小于2那么这个点所连接的边就一定不会拆开

如果这个点的读书是大于或者等于2

此时如果这个点和它的父节点不断开,那么它的子节点就只能保存一个

反之如果它和父节点断开,那么子节点可以保存两个

这样分析一下断开父节点一定是最优的情况

所以我们根据每个节点的子节点个数来找最后的步骤数

node子节点个数为s

s>=2 断开父节点+1,断开s-2个子节点+(s-2)

将s-2个子节点连接+(s-2)

将断开的node点与父节点部分相连接+1

如果node为根节点那么就不需要断开父节点,和与父节点再次相连接

/********************************************
Author         :Crystal
Created Time   :
File Name      :
********************************************/
#pragma comment(linker, "/STACK:1024000000,1024000000")//阔栈 
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <climits>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#include <cctype>
using namespace std;
typedef long long ll;
typedef pair<int ,int> pii;
#define MEM(a,b) memset(a,b,sizeof a)
#define CLR(a) memset(a,0,sizeof a);
const int inf = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
//#define LOCAL
#define maxn 2100000
int nxt[maxn],pnt[maxn],head[maxn];
int cnt;
int n;
int ans=0;
void addedge(int u,int v){
pnt[cnt]=v;
nxt[cnt]=head[u];
head[u]=cnt++;
}
int dfs(int u,int pre){
int s = 0;
for(int i=head[u];i!=-1; i = nxt[i]){
int v = pnt[i];
if(v != pre){
s+=dfs(v,u);
}
}
if(s >= 2){
if(u==1) ans += 2*(s-2);
else ans += 2*(s-2)+2;
return 0;
}
return 1;
}
int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("out.txt","w",stdout);
#endif
int t;
scanf("%d",&t);
while(t--){
for(int i=0;i<maxn;i++)head[i]=-1;
cnt = 1;
scanf("%d",&n);
ans = 0;
for(int i=0;i<n-1;i++){
int u,v;scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
dfs(1,-1);
printf("%d\n",ans+1);
}
return 0;
}
















阅读更多
文章标签: 树形dp dp
个人分类: dp
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭