其实我不是想做这道题的...只是今天考试考了一道类似的题...然后我挂了...

但是乱搞一下还是有80分....可惜没想到正解啊!

所以今天的考试题是:

巡访 (path.pas/c/cpp)

  Chanxer终于当上了“中华农民联盟”的盟主,他举目四望,决定四处走走,巡视自己的农土。

  “中华农民联盟”的成员有个村庄,在“村村通”计划中,村庄们被条道路联通了起来,Chanxer计划从某个村庄出发,访问所有的村庄。

可是Chanxer出行有一个特殊的要求,那就是必须以农车代步,现在我们知道哪些村庄配备有农车,也就是说,只有配备有农车的村庄才能够被作为出发点。

Chanxer有点懒,他想知道访问全部的村庄所要走的路程长度最小是多少。

树的节点数 n<=10^5

题目大意:已知一棵树,求一条满足一个端点为给定的端点的最长链。

其实就是求出每个点能到达的最远距离  [这就是我们的标题所给题目要求的]。

所以应该怎么做呢?

方法一:

  经过证明,从树上任意一个点出发到达的最远的点一定是这棵树的直径的一个端点。

  反过来,从直径的端点出发到达每个点的距离也一定是最远距离...  [我怎么就没想到...囧]

  所以先找到两个端点[先从随意一个点出发,然后这个点一定是一个端点,端点的最远点就是另一个端点],然后再跑一遍dfs就可以了[ 因为找第二个端点的时候已经跑过一遍了 ]...

  

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<queue>
#include<algorithm> using namespace std; inline int in(){
int x=;char ch=getchar();
while(ch>'' || ch<'') ch=getchar();
while(ch>='' && ch<='') x=x*+ch-'',ch=getchar();
return x;
} const int maxn=;
const int INF=0x3f3f3f3f; struct Node{
int data,next,weight;
}node[maxn<<]; #define now node[point].data
#define then node[point].next
#define www node[point].weight int n,cnt;
long long M_dis,M_sit=,M_dis1;
int star[maxn];
int head[maxn];
bool vis[maxn];
long long ans,Sum;
long long f[maxn]; inline void add(int u,int v,int w){
node[cnt].data=v;node[cnt].next=head[u];node[cnt].weight=w;head[u]=cnt++;
node[cnt].data=u;node[cnt].next=head[v];node[cnt].weight=w;head[v]=cnt++;
} int dfs(int x,long long sum){
vis[x]=true;
if(sum>M_dis)
M_dis=sum,M_sit=x;
for(int point=head[x];point!=-;point=then)
if(!vis[now])
dfs(now,sum+www);
vis[x]=false;
} int dfs2(int x,long long sum){
vis[x]=true;f[x]=max(f[x],sum);
if(sum>M_dis)
M_dis=sum,M_sit=x;
for(int point=head[x];point!=-;point=then)
if(!vis[now])
dfs2(now,sum+www);
vis[x]=false;
} int main(){
freopen("path.in","r",stdin);
freopen("path.out","w",stdout); int u,v,w,cot=; n=in();
for(int i=;i<=n;i++) head[i]=-;
for(int i=;i<n;i++){
u=in(),v=in(),w=in(),add(u,v,w);
Sum+=w<<;
}
for(int i=;i<=n;i++) star[i]=in(),cot+=star[i]; dfs(,);
int t=M_sit;
dfs2(t,);
dfs2(M_sit,); for(int i=;i<=n;i++)
if(star[i])
ans=max(ans,f[i]); ans=Sum-ans; printf("%lld",ans); return ;
}

方法二:

  

详情可以见代码

 #include<cstdio>
#include<cstring>
#include<algorithm> using namespace std; inline int in(){
int x=;char ch=getchar();
while(ch>'' || ch<'') ch=getchar();
while(ch>='' && ch<='') x=x*+ch-'',ch=getchar();
return x;
} const int maxn=; struct Node{
int data,next,weight;
}node[maxn<<]; #define now node[point].data
#define then node[point].next
#define www node[point].weight int n,cnt,ans,Sum;
int head[maxn];
int Max[maxn],Maxv[maxn];
int Smax[maxn],Smaxv[maxn]; inline void add(int u,int v,int w){
node[cnt].data=v;node[cnt].next=head[u];node[cnt].weight=w;head[u]=cnt++;
node[cnt].data=u;node[cnt].next=head[v];node[cnt].weight=w;head[v]=cnt++;
} void dfs(int x,int p){
for(int point=head[x];point!=-;point=then){
if(now==p) continue;
dfs(now,x);
if(Smax[x]<Max[now]+www){
Smax[x]=Max[now]+www,Smaxv[x]=now;
if(Smax[x]>Max[x]){
swap(Smax[x],Max[x]);
swap(Smaxv[x],Maxv[x]);
}
}
}
} void dfs2(int x,int p){
for(int point=head[x];point!=-;point=then){
if(now==p) continue;
if(now==Maxv[x]){
if(Smax[now]<Smax[x]+www){
Smax[now]=Smax[x]+www;Smaxv[now]=x;
if(Smax[now]>Max[now]){
swap(Smax[now],Max[now]);
swap(Smaxv[now],Maxv[now]);
}
}
}
else{
if(Smax[now]<Max[x]+www){
Smax[now]=Max[x]+www;Smaxv[now]=x;
if(Smax[now]>Max[now]){
swap(Smax[now],Max[now]);
swap(Smaxv[now],Maxv[now]);
}
}
}
dfs2(now,x);
}
} int main(){
freopen("path.in","r",stdin);
freopen("path.out","w",stdout); int u,v,w; n=in();
for(int i=;i<=n;i++) head[i]=-;
for(int i=;i<n;i++)
u=in(),v=in(),w=in(),add(u,v,w),Sum+=(w<<); dfs(,-);
dfs2(,-); for(int i=;i<=n;i++)
if(u=in()) ans=max(ans,Max[i]); printf("%d",Sum-ans); return ;
}

另附标题的AC通道:

http://acm.hdu.edu.cn/showproblem.php?pid=2196

HDU 2196 求树上所有点能到达的最远距离的更多相关文章

  1. HDU 2196 Computer (树上最长路)【树形DP】

    <题目链接> 题目大意: 输出树上每个点到其它点的最大距离. 解题分析: 下面的做法是将树看成有向图的做法,计算最长路需要考虑几种情况. dp[i][0] : 表示以i为根的子树中的结点与 ...

  2. HDU 2196 Computer( 树上节点的最远距离 )

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  3. hdu 2196(方法1:经典树形DP+方法2:树的直径)

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  4. 求树上任意一点所能到达的最远距离 - 树上dp

    A school bought the first computer some time ago(so this computer's id is 1). During the recent year ...

  5. HDU 2196.Computer 树形dp 树的直径

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  6. HDU 2196树形DP(2个方向)

    HDU 2196 [题目链接]HDU 2196 [题目类型]树形DP(2个方向) &题意: 题意是求树中每个点到所有叶子节点的距离的最大值是多少. &题解: 2次dfs,先把子树的最大 ...

  7. hdu 2196【树形dp】

    http://acm.hdu.edu.cn/showproblem.php?pid=2196 题意:找出树中每个节点到其它点的最远距离. 题解: 首先这是一棵树,对于节点v来说,它到达其它点的最远距离 ...

  8. HDU 2196 树形DP Computer

    题目链接:  HDU 2196 Computer 分析:   先从任意一点开始, 求出它到其它点的最大距离, 然后以该点为中心更新它的邻点, 再用被更新的点去更新邻点......依此递推 ! 代码: ...

  9. 【HDU 2196】 Computer(树的直径)

    [HDU 2196] Computer(树的直径) 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 这题可以用树形DP解决,自然也可以用最直观的方法解 ...

随机推荐

  1. C#语法基础和面向对象编程

    1.C#语法基础 http://www.cnblogs.com/tonney/archive/2011/03/16/1986456.html 2.C#与面向对象基础 很棒的资源,简明扼要,介绍的非常清 ...

  2. [leetcode]_Merge Sorted Array

    题目:合并两个有序数组A , B,将合并后的数组存到A中.假设A的空间足够装下A和B所有的元素. 思路:这道题考虑如果正向扫描两个数组,则每插入一个元素,则需移动A后的所有元素.换个角度想,既然元素个 ...

  3. LevelDB源码之四LOG文件

    “LOG文件在LevelDb中的主要作用是系统故障恢复时,能够保证不会丢失数据.因为在将记录写入内存的Memtable之前,会先写入Log文件,这样即使系统发生故障,Memtable中的数据没有来得及 ...

  4. JDBC基础二

    1.配置文件:dbinfo.properties driverClass=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/test user ...

  5. virtualenv python虚拟环境搭建

    python virtualenv.py flask

  6. [转]C++编写Config类读取配置文件

    //Config.h #pragma once #include <string> #include <map> #include <iostream> #incl ...

  7. SQL Server Analysis Services 数据挖掘

    假如你有一个购物类的网站,那么你如何给你的客户来推荐产品呢?这个功能在很多 电商类网站都有,那么,通过SQL Server Analysis Services的数据挖掘功能,你也可以轻松的来构建类似的 ...

  8. iOS学习之Object-C语言集合

    一.数组类      1.C语言数组的特点:数组是一个有序的集合,用来存储相同数据类型的元素,通过下标访问数组中的元素,下标从0开始.      2.OC中的数组只能存储对象类型(必须是NSObjec ...

  9. OC中的消息传递和初始化

    [receiver message]:[接收者 消息] 把消息传递给接收者. getter(接收器),setter(设置器):只设置和读取一个参数. Person *p1 = [[Person all ...

  10. [转]tftp在put上传的时候显示File not found的解决办法

    [转]tftp在put上传的时候显示File not found的解决办法 http://blog.163.com/pengcz%40126/blog/static/35908607201182433 ...