2017湘潭大学邀请赛H题(树的直径)

链接:https://www.icpc.camp/contests/4mYguiUR8k0GKE

H. Highway

The input contains zero or more test cases and is terminated by end-of-file. For each test case: The first line contains an integer n. The i-th of the following (n ? 1) lines contains three integers ai , bi and ci

. ? 1 ≤ n ≤ 105

? 1 ≤ ai , bi ≤ n

? 1 ≤ ci ≤ 108

? The number of test cases does not exceed 10.

题意:

每次连接最远的两点,直到所有点都相通。

最多有n-1条边

题解:

如何每次都找到最远的两个点呢?

我们需要用到一个定理:树上的任何一个点的最远点一定会是<树的直径>中的一个

树的直径指:树上的最远的两个点

接下来我们证明这个定理——

1,利用这个定理,我们可以从<1节点>dfs找到一个直径上的点。

2,用直径上的这个点dfs可以找到另外一个直径上的点。

3,找出所有点到这两个直径上的点的距离

4,将所有点都连接在直径的两个点之一,就是答案了

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int f[maxn],nex[2*maxn],w[2*maxn],tob[2*maxn],inde;
long long  dis1[maxn],dis2[maxn];
bool vis[maxn];
long long  s1,maxdis,s2;
long long  madis=-1;
void add(int a,int b,int wn)
{
    inde++;
    tob[inde]=b;
    w[inde]=wn;
    nex[inde]=f[a];
    f[a]=inde;
}
void dfs1(int x,long long  v)
{
    vis[x]=0;
    for(int i=f[x];i;i=nex[i])
    {
        if(vis[tob[i]])
        {
            long long  gg=v+w[i];
            if(gg>madis)
            {

                madis=gg;
                s1=tob[i];
            }
            dfs1(tob[i],gg);
        }
    }
}
void dfs2(int x,long long v)
{
     vis[x]=0;
    for(int i=f[x];i;i=nex[i])
    {
        if(vis[tob[i]])
        {
            long long gg=v+w[i];
            if(gg>maxdis)
            {
                maxdis=gg;
                s2=tob[i];
            }
            dis1[tob[i]]=gg;
            dfs2(tob[i],gg);
        }
    }
}
void dfs3(int x,long long  v)
{
    vis[x]=0;
    for(int i=f[x];i;i=nex[i])
    {
        if(vis[tob[i]])
        {
            long long gg=v+w[i];
            dis2[tob[i]]=gg;
            dfs3(tob[i],gg);
        }
    }
}
int main()
{
    int n;
    while(cin>>n)
    {
        inde=0;
        for(int i=1;i<=n;i++)f[i]=0;
        for(int i=1;i<n;i++)
        {
            int a,b,wn;
            scanf("%d %d %d",&a,&b,&wn);
            add(a,b,wn);
            add(b,a,wn);
        }
        maxdis=madis=-1;
        for(int i=1;i<=n;i++)vis[i]=1;
        dfs1(1,0);
        for(int i=1;i<=n;i++)vis[i]=1;
        dfs2(s1,0);
        for(int i=1;i<=n;i++)vis[i]=1;
        dfs3(s2,0);
        long long  ans=maxdis;
        for(int i=1;i<=n;i++)
        {
            if(i==s1||i==s2)continue;
            ans+=max(dis1[i],dis2[i]);
        }
        cout<<ans<<endl;
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/carcar/p/9023117.html

时间: 2024-10-09 13:17:06

2017湘潭大学邀请赛H题(树的直径)的相关文章

2017湘潭大学邀请赛E题(贪心)

链接:https://www.icpc.camp/contests/4mYguiUR8k0GKE Partial Sum Input The input contains zero or more test cases and is terminated by end-of-file. For each test case: The first line contains three integers n, m, C. The second line contains n integers a1

HDU 6271 Master of Connected Component(2017 CCPC 杭州 H题,树分块 + 并查集的撤销)

题目链接  2017 CCPC Hangzhou Problem H 思路:对树进行分块.把第一棵树分成$\sqrt{n}$块,第二棵树也分成$\sqrt{n}$块.    分块的时候满足每个块是一个连通块,那么每个块就有一个共同的祖先. 把询问按照第一个点被第一棵树的哪个祖先管辖和第二个点被第二棵树的哪个祖先管辖,分成$n$类. 每一类询问一起处理,处理完后用可撤销并查集恢复到之前的状态. 每一类询问之间依次转移,每次转移,移动次数不会超过$\sqrt{n}$次. 最后总时间复杂度$O(n^{

HDOJ Page Rank 5097【2014上海邀请赛H题-简单矩阵】

Page Rank Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Others) Total Submission(s): 282    Accepted Submission(s): 77 Problem Description Evaluation and rank of web pages is a hot topic for many internet companies and

2017端午欢乐赛——Day1T3(树的直径+并查集)

//前些天的和jdfz的神犇们联考的模拟赛.那天上午大概是没睡醒吧,考场上忘了写输出-1的情况,白丢了25分真是**. 题目描述     小C所在的城市有 n 个供电站,m条电线.相连的供电站会形成一个供电群,那么为了节省材料,供电群是一棵树的形式,也即城市是一个森林的形式(树:V个点,V-1条边的无向连通图,森林:若干棵树).每个供电群中不需要所有供电站都工作,最少只需要一个工作,其余的就都会通过电线收到电,从而完成自己的供电任务.当然,这样会产生延迟.定义两个供电站的延迟为它们之间的电线数量

poj1985&amp;&amp;第四次CCF软件认证第4题 求树的直径

Cow Marathon Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 4216   Accepted: 2137 Case Time Limit: 1000MS Description After hearing about the epidemic of obesity in the USA, Farmer John wants his cows to get more exercise, so he has com

HDU - 4788 Hard Disk Drive (成都邀请赛H 水题)

HDU - 4788 Hard Disk Drive Time Limit:1000MS   Memory Limit:32768KB   64bit IO Format:%I64d & %I64u [Submit]  [Go Back]  [Status] Description Yesterday your dear cousin Coach Pang gave you a new 100MB hard disk drive (HDD) as a gift because you will

[xyz模拟题]动态维护树的直径

专出神题的xyz. 支持删加边.修改点权.维护树的直径. LCT 需要额外记录子树信息.用一个堆维护. #include<cstdio> #include<cstring> #include<algorithm> #include<set> #include<vector> #include<queue> using namespace std; #define rep(i,x,y) for(i=x;i<=y;i++) #def

Lightoj 1094 - Farthest Nodes in a Tree 【树的直径 裸题】

1094 - Farthest Nodes in a Tree PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB Given a tree (a connected graph with no cycles), you have to find the farthest nodes in the tree. The edges of the tree are weighted and undire

HDU 5886 Tower Defence(2016青岛网络赛 I题,树的直径 + DP)

题目链接  2016 Qingdao Online Problem I 题意  在一棵给定的树上删掉一条边,求剩下两棵树的树的直径中较长那的那个长度的期望,答案乘上$n-1$后输出. 先把原来那棵树的直径求出来.显然删掉的边不是这条直径上的边,那么这时答案就是这条直径的长度. 否则就是直径的某个端点到某一个点(要求连通)的距离的最大值. 在整条链上做两次$DP$之后枚举取较大值即可. #include <bits/stdc++.h> using namespace std; #define r