[SDOI 2013] 直径

[题目链接]

          https://www.lydsy.com/JudgeOnline/problem.php?id=3124

[算法]

         树的直径

[代码]

         

#include<bits/stdc++.h>
using namespace std;
#define MAXN 200010

struct edge
{
        int to,w,nxt;
} e[MAXN << 1];

int i,n,s,t,cnt,tmp,tot,u,v,w,l,r;
long long mx;
int path[MAXN],head[MAXN],pre[MAXN];
long long dist[MAXN];
bool visited[MAXN];

inline void addedge(int u,int v,int w)
{
        tot++;
        e[tot] = (edge){v,w,head[u]};
        head[u] = tot;
}
inline int bfs(int s)
{
        int i,u,v,w,l,r,pos;
        static int q[MAXN];    
        static bool visited[MAXN];
        for (i = 1; i <= n; i++) visited[i] = false;
        q[l = r = 1] = s;
        dist[s] = 0;
        pre[s] = 0;
        visited[s] = true;
        while (l <= r)
        {
                u = q[l];
                l++;
                for (i = head[u]; i; i = e[i].nxt)
                {
                        v = e[i].to;
                        w = e[i].w;
                        if (!visited[v])
                        {
                                visited[v] = true;
                                dist[v] = (long long)dist[u] + w;
                                pre[v] = u;
                                q[++r] = v;
                        }
                }        
        }    
        pos = 1;
        for (i = 2; i <= n; i++)
        {
                if (dist[i] > dist[pos])
                        pos = i;
        }
        return pos;
}
inline void dfs(int u,int fa,long long sum)
{
        int i,v,w;
        mx = max(mx,sum);
        for (i = head[u]; i; i = e[i].nxt)
        {
                v = e[i].to;
                w = e[i].w;
                if (v != fa && !visited[v]) dfs(v,u,sum + w);
        }
}

int main() 
{
        
        scanf("%d",&n);
        for (i = 1; i < n; i++)
        {
                scanf("%d%d%d",&u,&v,&w);
                addedge(u,v,w);
                addedge(v,u,w); 
        }
        s = bfs(1);
        t = bfs(s);
        printf("%lld\n",dist[t]);
        tmp = t;
        while (tmp != 0)
        {
                path[++cnt] = tmp;
                tmp = pre[tmp];
                visited[tmp] = true;
        }
        reverse(path + 1,path + cnt + 1);
        l = 1,r = cnt;
        for (i = cnt; i >= 1; i--)
        {
                mx = 0;
                dfs(path[i],0,0);
                if (!mx) continue;
                if (mx == dist[t] - dist[path[i]]) r = i;
                if (mx == dist[path[i]]) 
                {
                        l = i;
                        break;
                }
        }
        printf("%d\n",r - l);
        
        return 0;
    
}

 

posted @ 2018-08-06 22:37  evenbao  阅读(146)  评论(0编辑  收藏  举报