hdu 3721 uvalive 5026 building roads
来源:互联网 发布:安卓源码如何生成apk 编辑:程序博客网 时间:2024/05/22 03:47
首先,我们证明一个结论:树的重心一定在树的直径上
树的直径指树上最长的一条路径,树的重心指树上所有点中到其余点最远距离最小的点
假设重心u不在直径上,那么它到距它最远点(x)的路径一定会和树的直径有交点v,否则这条路径会是新的直径的一部分,那么v到x的距离一定更小,所以重心一定在直径上
显然,我们需要移走直径上的一条边,并且移走这条边后,原来的树变成了两棵树(特殊情况是移走和叶子相连的一条边,但不影响)
那这样子,这两棵树,每棵树都有自己的直径d1,d2,那么将两棵树重新合并后,当前最优解tmp>=max(d1,d2)
我们在树1中和树2中分别找重心,新合并的树上任意点到最远点距离的最小值也可能是是树1中的重心的相对应的值x+树2中的重心相对应的值y+枚举的边长w
即tmp=max(tmp,w+x+y)
代码:
#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<cmath>#include<stack>#include<queue>#include<vector>#include<map>#include<ctime>using namespace std;const int MAX=2555;struct node {int v,w,next,flag;}g[MAX*10];int adj[MAX],e,n,m,dis[MAX],pre[MAX],D,tot,tmp[MAX],res[MAX];void add(int u,int v,int w){g[e].v=v; g[e].w=w; g[e].flag=1; g[e].next=adj[u]; adj[u]=e++;}void dfs(int u,int fa,int w,int id){int i,v;pre[u]=id;dis[u]=w;D=max(D,w);for(i=adj[u];i!=-1;i=g[i].next){v=g[i].v;if(v==fa||!g[i].flag)continue;dfs(v,u,w+g[i].w,i);}}void find(int root){memset(dis,0,sizeof(dis));dfs(root,-1,0,-1);int ma=-1,i,j;for(i=1;i<=n;i++)if(dis[i]>ma){ma=dis[i];j=i;}memset(dis,0,sizeof(dis));D=-1;dfs(j,-1,0,-1);}void find_path(int t,int res[],int &tot){int i;tot=0;for(i=pre[t];i!=-1;i=pre[g[i^1].v]){res[tot++]=i;}}void solve(){int ans,i,j,x,y,k;find(1);ans=1<<30;for(i=1;i<=n;i++){if(dis[i]==D){find_path(i,res,tot);break;}}//cout<<"tot="<<tot<<endl;for(i=0;i<tot;i++){//cout<<g[res[i]].v<<endl;g[res[i]].flag=0;g[res[i]^1].flag=0;find(g[res[i]].v);int d1=D,n1,n2;for(j=1;j<=n;j++){if(dis[j]==D){find_path(j,tmp,n1);break;}}if(d1==0)x=0;elsex=1<<30;for(j=0;j<n1;j++){k=g[tmp[j]].v;x=min(x,max(dis[k],D-dis[k]));k=g[tmp[j]^1].v;x=min(x,max(dis[k],D-dis[k]));}find(g[res[i]^1].v);int d2=D;for(j=1;j<=n;j++){if(dis[j]==D){find_path(j,tmp,n2);break;}}if(d2==0)y=0;elsey=1<<30;for(j=0;j<n2;j++){k=g[tmp[j]].v;y=min(y,max(dis[k],D-dis[k]));k=g[tmp[j]^1].v;y=min(y,max(dis[k],D-dis[k]));}g[res[i]].flag=1;g[res[i]^1].flag=1;d1=max(d1,d2);d1=max(d1,g[res[i]].w+x+y);ans=min(ans,d1);}printf("%d\n",ans);}int main(){int i,j,k,w,T;scanf("%d",&T);for(int ca=1;ca<=T;ca++){memset(adj,-1,sizeof(adj));e=0;scanf("%d",&n);for(i=1;i<n;i++){scanf("%d%d%d",&j,&k,&w);j++; k++;add(j,k,w); add(k,j,w);}printf("Case %d: ",ca);solve();}return 0;}
- hdu 3721 uvalive 5026 building roads
- HDU 3721 Building Roads
- HDU 3721 Building Roads
- 【树形DP】 HDU 3721 Building Roads
- 树形dp-hdu-3721-Building Roads
- hdu 3721 Building Roads 树的直径
- HDU 3721 Building Roads 树形dp + 枚举直径
- HDU 3721 - Building Roads(DFS`树的直径)
- 【HDU】1822 Building roads 2-sat
- HDU - 1815 Building roads (2-SAT)
- hdu 2590 Building roads(环+贪心)
- Building Roads
- HDU--3721[Building Roads] 枚举+求最长路O(N^2)
- HDU 3721 Building Roads (2010 Asia Tianjin Regional Contest) - from lanshui_Yang
- hdu 1815 Building roads(二分+2-sat判定)
- Poj 2749 & Hdu 1815 Building roads (2-SAT + 二分 建图)
- HDU 1815, POJ 2749 Building roads(2-sat)
- POJ 2749 && HDU 1815 Building roads(2-SAT+二分)
- Windows上Android开发环境搭建
- 讲座DEMO视频First Azure Application 下载
- 拥塞控制策略
- 腾讯一面
- 更改记事本的编码方式
- hdu 3721 uvalive 5026 building roads
- EMC2012笔试体会
- 网页资料-java反射机制
- Java 序列化的高级认识
- 2011年第36届大连赛区现场赛Board
- delphi调用cmd的两种方法
- sql server 数据导入到mysql数据库 出错??
- SQL操作全集--百度
- Build Rsync System