首页 > 代码库 > hdu4714(树形dp)
hdu4714(树形dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4714
题意:给你一棵树,,其中每去掉一条边或加一条边的代价均为1,让你求出将其变成一个圆的最小代价。
分析:由于该树要形成一个圆,所以对于分支大于等于2的子树,必须把它断开形成一条链,最后再连接起来。
定义N为1000010时不断超时,定义N为2000010时却1357ms,hdu这破oj真是让人无语。。。
#pragma comment(linker,"/STACK:102400000,102400000")#include <cstdio>#include <cstring>#include <cmath>#include <iostream>#include <algorithm>#include <queue>#include <cstdlib>#include <stack>#include <vector>#include <set>#include <map>#define LL long long#define mod 1000000007#define inf 0x3f3f3f3f#define N 2000010#define FILL(a,b) (memset(a,b,sizeof(a)))using namespace std;struct edge{ int next,v; edge(){} edge(int v,int next):v(v),next(next){}}e[N*2];int head[N],tot;int sum,n;void addedge(int u,int v){ e[tot]=edge(v,head[u]); head[u]=tot++;}int dfs(int u,int fa){ int tmp=0; //计算分支数,大于等于2时有分支。 for(int i=head[u];~i;i=e[i].next) { int v=e[i].v; if(v==fa)continue; tmp+=dfs(v,u); } if(tmp>=2) { if(u==1)sum+=2*(tmp-2); //如果是根节点的话,那么其有两条边在同一分支上。 else sum+=2*(tmp-1);//否则就是只能选择一条边在一个分支上 return 0; } return 1;}int main(){ int u,v,T; scanf("%d",&T); while(T--) { scanf("%d",&n); tot=0;sum=0; memset(head,-1,sizeof(head)); for(int i=1;i<n;i++) { scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } dfs(1,-1); printf("%d\n",sum+1); }}
hdu4714(树形dp)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。