Highway | ||
Accepted : 169 | Submit : 577 | |
Time Limit : 4000 MS | Memory Limit : 65536 KB |
HighwayIn ICPCCamp there were n towns conveniently numbered with 1,2,…,n connected with (n−1) roads. The i -th road connecting towns ai and bi has length ci . It is guaranteed that any two cities reach each other using only roads. Bobo would like to build (n−1) highways so that any two towns reach each using only highways. Building a highway between towns x and y costs him δ(x,y) cents, where δ(x,y) is the length of the shortest path between towns x and y using roads. As Bobo is rich, he would like to find the most expensive way to build the (n−1) highways. InputThe 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 .
OutputFor each test case, output an integer which denotes the result. Sample Input5 1 2 2 1 3 1 2 4 2 3 5 1 5 1 2 2 1 4 1 3 4 1 4 5 2 Sample Output19 15 SourceXTU OnlineJudge |
http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1267
本题的题意是真的坑爹 告诉你一颗树 你就可以求出两两的距离 再用这些距离去构造最大生成树 4到5的距离为6
此题需要知道一个东西 就是树的直径 http://www.cnblogs.com/xubenben/archive/2012/12/28/2837971.html
#include<stdio.h>
#include<vector>
#include<queue>
#include<string.h>
using namespace std;
#define ll long long
bool vis[100010];
ll gg[100010];
ll gg1[2][100010];
int pp;
ll total;
int qd;
struct node
{
int yd,val,et;
};
vector<node>ap[100010];
vector<node>ap1[100010];
int bfs(int ss)
{
int zd;
queue<int>qe;
qe.push(ss);
vis[ss]=1;
ll maxx=0;
while(!qe.empty())
{
int dt=qe.front();//原点
qe.pop();
for(int i=0; i<ap[dt].size(); i++)
{
node ft=ap[dt][i];
if(vis[ft.et]) continue;
vis[ft.et]=1;
gg[ft.et]=gg[dt]+ap[dt][i].val;
qe.push(ft.et);
if(maxx<gg[ft.et])
{
maxx=gg[ft.et];
zd=ft.et;
}
}
}
return zd;
}
void dfs(int k,ll sum)
{
for(int i=0; i<ap1[k].size(); i++)
{
int vv=ap1[k][i].et;
if(vis[vv]) continue;
vis[vv]=1;
dfs(vv,sum+ap1[k][i].val);
}
if(total<sum)
{
total=sum;
qd=k;
}
}
void dfs1(int k,ll sum)
{
for(int i=0; i<ap1[k].size(); i++)
{
int vv=ap1[k][i].et;
if(vis[vv]) continue;
vis[vv]=1;
gg1[pp][vv]=sum+ap1[k][i].val;
dfs1(vv,sum+ap1[k][i].val);
}
}
int main()
{
int n,i;
while(scanf("%d",&n)!=EOF)
{
for(i=0; i<=n; i++)
{
ap[i].clear();
ap1[i].clear();
}
node xf;
int u,v,w;
for(i=1; i<n; i++)
{
scanf("%d %d %d",&u,&v,&w);
xf.yd=u;
xf.et=v;
xf.val=w;
ap[u].push_back(xf);
ap1[u].push_back(xf);
xf.yd=v;
xf.et=u;
ap[v].push_back(xf);
ap1[v].push_back(xf);
}
memset(vis,0,sizeof(vis));
int zd=bfs(1); //求直径一端点
memset(vis,0,sizeof(vis));
total=0;
vis[zd]=1;
dfs(zd,0); //求直径长度
// printf("%d %d %I64d\n",qd,zd,total);
//求到两个端点的距离
memset(vis,0,sizeof(vis));
vis[zd]=1;
pp=0;
dfs1(zd,0);
memset(vis,0,sizeof(vis));
vis[qd]=1;
pp=1;
dfs1(qd,0);
ll sum=0;
gg1[0][zd]=0;
gg1[1][qd]=0;
for(i=1; i<=n; i++)
{
//printf("%I64d %I64d\n",gg1[0][i],gg1[1][i]);
sum+=max(gg1[0][i],gg1[1][i]);
}
sum-=gg1[0][qd];
printf("%I64d\n",sum);
}
return 0;
}