POJ 1985 - 树的直径

传送门

题目大意

给一颗n个点的树,求树的直径(最长的一条链)

题解

先随便找一个点u,dfs出离它最远的点v

于是有以下情况:

  • 直径就是这条链
  • 直径经过u,是这条链的延长
  • 直径不经过u

只需要从v再进行一边dfs,便可以求出直径。

code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;

int n, m;
int adj[50005], nxt[100005], go[100005], len[100005], ecnt;
long long dist[50005];

inline void addEdge(int u, int v, int w){
	nxt[++ecnt] = adj[u], adj[u] = ecnt, go[ecnt] = v, len[ecnt] = w;
	nxt[++ecnt] = adj[v], adj[v] = ecnt, go[ecnt] = u, len[ecnt] = w;
}

inline void dfs(int u, int f){
	for(int e = adj[u]; e; e = nxt[e]){
		int v = go[e];
		if(v == f) continue;
		dist[v] = dist[u] + len[e];
		dfs(v, u);
	}
}

int main(){
	freopen("h.in", "r", stdin);
	while(~scanf("%d%d", &n, &m)){
		ecnt = 0;
		memset(adj, 0, sizeof adj);
		for(int i = 1; i <= m; i++){
			int u, v, w; char ch;
			scanf("%d %d %d %c", &u, &v, &w, &ch);
			addEdge(u, v, w);
		}
		int v; long long ret = 0;
		dist[1] = 0;
		dfs(1, 0);
		for(int i = 1; i <= n; i++)
			if(ret < dist[i]) ret = dist[i], v = i;
		dist[v] = ret = 0;
		dfs(v, 0);
		for(int i = 1; i <= n; i++)
			if(ret < dist[i]) ret = dist[i], v = i;
		printf("%lld\n", ret);
	}
}
posted @ 2017-08-31 18:59  CzYoL  阅读(250)  评论(0编辑  收藏  举报