码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ3124 直径

时间:2018-04-05 23:39:51      阅读:278      评论:0      收藏:0      [点我收藏+]

标签:view   span   click   namespace   sizeof   div   return   log   hid   

Description:

求树的直径的必须边

 

思路:求出任意一条直径,然后对这条直径的每个点进行DFS(不过直径任何点),定义一个l,r,初始为直径的两端,然后计算出该点能到的最远距离如果等于其左端或右端,那么l = pos 或者 r = pos。

注意因为是从右向左搜的,所以左边的点只要收一次,且越早越好。

技术分享图片
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int N = 1e6 + 10;

int head[N], now = 1;
struct edges{
    int to, next, w;
}edge[N<<1];
void add(int u, int v, int w){ edge[++now] = {v, head[u], w}; head[u] = now;}

int n, m, pre[N], tot, pos1, pos2;
bool isd[N];
long long dep[N], mx;
void dfs1(int x){
    for(int i = head[x]; i; i = edge[i].next){
        int v = edge[i].to;
        if(pre[x] == v) continue;
        pre[v] = x;
        dep[v] = dep[x] + edge[i].w;
        dfs1(v);
    }
}
void dfs(int x, int fa){
    for(int i = head[x]; i; i = edge[i].next){
        int v = edge[i].to;
        if(v == fa || isd[v]) continue;
        dep[v] = dep[x] + edge[i].w;
        mx = max(dep[v], mx);
        dfs(v, x);
    }
}
int main(){
    scanf("%d", &n);
    for(int i = 1; i < n; i++){
        int x, y, z;
        scanf("%d%d%d", &x, &y, &z);
        add(x, y, z); add(y, x, z);
    }
    dfs1(1);
    mx = 0;
    for(int i = 1; i <= n; i++)
      if(dep[i] > mx) mx = dep[i], pos1 = i;
    memset(dep, 0, sizeof(dep));
    memset(pre, 0, sizeof(pre));
    dfs1(pos1);
    mx = 0;
    for(int i = 1; i <= n; i++)
      if(dep[i] > mx) mx = dep[i], pos2 = i;
    for(int i = pos2; i; i = pre[i])
      isd[i] = 1;
    bool flag = 0;
    int l = pos1, r = pos2;
    long long ans = dep[pos2] - dep[pos1];
    for(int i = pre[pos2]; i != pos1; i = pre[i]){
        dfs(i, -1);
        int ls = dep[i], rs = dep[pos2] - dep[i];
        dep[i] = mx = 0;
        dfs(i, -1);
        if(mx == rs) r = i;
        if(mx == ls && !flag) 
          flag = 1, l = i;
    }
    for(int i = r; i != l; i = pre[i]) tot++; 
    printf("%lld\n%d\n",ans, tot);
    return 0;
}
View Code

BZOJ3124 直径

标签:view   span   click   namespace   sizeof   div   return   log   hid   

原文地址:https://www.cnblogs.com/Rorshach/p/8724829.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!