hdu 4607 (树形DP)
来源:互联网 发布:淘宝店铺搜索搜不出来 编辑:程序博客网 时间:2024/05/21 06:54
当时比赛的时候我们找出来只要求出树的最长的边的节点数ans,如果要访问点的个数n小于ans距离直接就是n-1
如果大于的话就是(n-ans)*2+ans-1,当时求树的直径难倒我们了,都不会树形dp
选一个点当根每次求出一点到子节点的最大距离和次大距离,两个的和最大的就是树的直径
还在网上看到一种方法,任意一点广搜达到最远点max,再从max广搜,到达最远点就是树的直径
自己想了想这种方法:如果中间有点有分支的话,那么这点的最大分支一定是到max的
但是它的次大分支就不一定是到起点的,所以从max搜的话肯定是到这点的次大分支,就是直径了
#include<stdio.h>#include<string.h>#define N 100001int head[N],num,ins[N],n;struct edge{ int ed,next;}E[N*2];void addedge(int x,int y){ E[num].ed=y; E[num].next=head[x]; head[x]=num++;}int dis;int dist(int u){ ins[u]=1; int max=0,mmax=0; for(int i=head[u];i!=-1;i=E[i].next) { int v=E[i].ed; if(ins[v]==1)continue; int temp=dist(v); if(temp>mmax) { max=mmax; mmax=temp; } else if(temp>max) { max=temp; } } if(dis<(mmax+max+1)) dis=mmax+max+1; return mmax+1;}int main(){ int i,m,x,y,t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); memset(head,-1,sizeof(head)); num=0; for(i=0;i<n-1;i++) { scanf("%d%d",&x,&y); addedge(x,y); addedge(y,x); } memset(ins,0,sizeof(ins)); dis=0; dist(1); for(i=1;i<=m;i++) { scanf("%d",&x); if(x<=dis) printf("%d\n",x-1); else printf("%d\n",dis+(x-dis)*2-1); } } return 0;}
#include<stdio.h>#include<queue>#include<string.h>#define N 100001using namespace std;int head[N],num,vis[N],n;struct edge{ int ed,next;}E[N*2];struct node{int x,w;}cur,next;void addedge(int x,int y){ E[num].ed=y; E[num].next=head[x]; head[x]=num++;}int dist(){int i,v;memset(vis,0,sizeof(vis));queue<node>Q1,Q2;cur.x=1;Q1.push(cur);while(!Q1.empty()){ cur=Q1.front(); Q1.pop(); vis[cur.x]=1; for(i=head[cur.x];i!=-1;i=E[i].next) { next.x=v=E[i].ed; if(vis[v]==0) Q1.push(next); }}cur.w=1;Q2.push(cur);//广搜最后出来的点一点是最远点memset(vis,0,sizeof(vis));while(!Q2.empty()){cur=Q2.front();Q2.pop();vis[cur.x]=1;for(i=head[cur.x];i!=-1;i=E[i].next){next.x=v=E[i].ed;next.w=cur.w+1;if(vis[v]==0) Q2.push(next);}}return cur.w;}int main(){ int i,m,x,y,t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); memset(head,-1,sizeof(head)); num=0; for(i=0;i<n-1;i++) { scanf("%d%d",&x,&y); addedge(x,y); addedge(y,x); } int dis=dist(); for(i=1;i<=m;i++) { scanf("%d",&x); if(x<=dis) printf("%d\n",x-1); else printf("%d\n",dis+(x-dis)*2-1); } } return 0;}
- hdu 4607 (树形DP)
- hdu 4607 树形dp 树的直径
- 树形dp hdu Computer
- 【树形DP】hdu 1520
- hdu 1054 #树形DP
- hdu 4303 树形dp
- hdu 4340 树形dp
- hdu 4340 树形DP
- HDU 4340 树形DP
- hdu 4267 树形dp
- hdu 4383 树形dp
- HDU 2196 树形dp
- HDU 2196 树形dp
- hdu 1054 树形dp
- HDU 4276 树形DP
- hdu 2196 树形dp
- hdu 4044 树形dp
- hdu 1520-树形DP
- Apache MINA简介
- Struts2的hello world教程
- POJ-3268-Silver Cow Party
- android.intent.action.TIME_TICK在清单文件里注册不起作用
- Android普通方式的DoPost请求提交数据
- hdu 4607 (树形DP)
- uva 327 Evaluating Simple C Expressions(遍历)
- std::map key=std::pair
- linux rsync安装使用
- 《深入理解Android》导读之init
- c++实现一个自杀程序
- oracle 11g不能导出空表的解决方法
- poj 3694 Network LCA最小公共祖先
- hdu 2212