这个题目和HDU 4514:湫湫系列故事-设计风景线 这个题目所用的方法是一样的。
从题意可知,题目让求得是给出的图中最长路径。
题目中描述图连通,且有n-1条边。则对于一个连通块,我们可以选择从任意起点出发,求距该起点最远的点,
记为newStart。然后再从newStart出发,求距离newStart最远的点,这个距离就是图中任意两点距离中的最大
值。然后再算花费即可。这个题目虽然归类为难题。但是它真的不难。
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <string.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 1000000;
int head[maxn],cnt,vis[maxn];
ll dist;
struct Edge{
int v,nex;
ll w;
}edge[maxn*2];
typedef struct Node {
int x;
ll dis;
}node;
void addEdge(int u,int v,ll w) {
edge[cnt].v = v;
edge[cnt].w = w;
edge[cnt].nex = head[u];
head[u] = cnt++;
edge[cnt].v = u;
edge[cnt].w = w;
edge[cnt].nex = head[v];
head[v] = cnt++;
}
int bfs(int Start) {
int source;
node cur,nex;
memset(vis,0,sizeof(vis));
queue<node>qu;
cur.x = Start;
cur.dis = 0;
vis[Start] = 1;
qu.push(cur);
dist = 0;
source = Start;
int a,b;
while(!qu.empty()) {
cur = qu.front();
qu.pop();
a = cur.x;
if(cur.dis > dist) {
dist = cur.dis;
source = a;
}
int i;
for(i=head[a]; i!=-1; i=edge[i].nex) {
b = edge[i].v;
if(vis[b]==0) {
vis[b] = 1;
nex.x = b;
nex.dis = cur.dis + edge[i].w;
qu.push(nex);
}
}
}
return source;
}
int main() {
int n,u,v;
ll w;
while(~scanf("%d",&n)) {
cnt = 0;
memset(head,-1,sizeof(head));
for(int i = 1; i < n; i++) {
scanf("%d%d%lld",&u,&v,&w);
addEdge(u,v,w);
}
int newStart = bfs(1); //可以选图中任意点为起点,在此我选择1
bfs(newStart); //从距1最远的点newStart开始找离newStart最远的点。
ll ans;
//可以按照等差数列公式直接求解答案。
if(dist%2==0) {
ans = dist/2;
ans = ans*(dist+1);
}
else {
ans = (dist+1)/2;
ans = ans*dist;
}
ans += dist*10;
printf("%lld\n",ans);
}
return 0;
}