很久以前,T王国空前繁荣。为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市。
为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首都直接或者通过其他大城市间接到达。同时,如果不重复经过大城市,从首都到达每个大城市的方案都是唯一的。
J是T国重要大臣,他巡查于各大城市之间,体察民情。所以,从一个城市马不停蹄地到另一个城市成了J最常做的事情。他有一个钱袋,用于存放往来城市间的路费。
聪明的J发现,如果不在某个城市停下来修整,在连续行进过程中,他所花的路费与他已走过的距离有关,在走第x千米到第x+1千米这一千米中(x是整数),他花费的路费是x+10这么多。也就是说走1千米花费11,走2千米要花费23。
J大臣想知道:他从某一个城市出发,中间不休息,到达另一个城市,所有可能花费的路费中最多是多少呢?
输入的第一行包含一个整数n,表示包括首都在内的T王国的城市数
城市从1开始依次编号,1号城市为首都。
接下来n-1行,描述T国的高速路(T国的高速路一定是n-1条)
每行三个整数Pi, Qi, Di,表示城市Pi和城市Qi之间有一条高速路,长度为Di千米。
输出一个整数,表示大臣J最多花费的路费是多少。
1 2 2
1 3 1
2 4 5
2 5 4
大臣J从城市4到城市5要花费135的路费。
原理: 设起点为u,第一次BFS找到的终点v一定是树的直径的一个端点
证明: 1) 如果u 是直径上的点,则v显然是直径的终点(因为如果v不是的话,则必定存在另一个点w使得u到w的距离更长,则于BFS找到了v矛盾)
2) 如果u不是直径上的点,则u到v必然于树的直径相交(反证),那么交点到v 必然就是直径的后半段了
bfs:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <stack>
using namespace std;
typedef long long ll;
#define PI 3.1415926535897932
#define E 2.718281828459045
#define INF 0x3f3f3f3f
#define mod 100000007
const int M=1005;
int n,m;
int cnt;
int sx,sy,sz;
//int g[M][M];
int pa[M*10],rankk[M];
int head[M*6],vis[M*100];
int dis[M*100];
ll prime[M*1000];
bool isprime[M*1000];
int lowcost[M],closet[M];
char st1[5050],st2[5050];
int len[M*6];
typedef pair<int ,int> ac;
//vector<int> g[M*10];
int dp[M];
int has[10500];
int month[13]= {0,31,59,90,120,151,181,212,243,273,304,334,0};
int dir[8][2]= {{0,1},{0,-1},{-1,0},{1,0},{1,1},{1,-1},{-1,1},{-1,-1}};
void getpri()
{
ll i;
int j;
cnt=0;
memset(isprime,false,sizeof(isprime));
for(i=2; i<1000000LL; i++)
{
if(!isprime[i])prime[cnt++]=i;
for(j=0; j<cnt&&prime[j]*i<1000000LL; j++)
{
isprime[i*prime[j]]=1;
if(i%prime[j]==0)break;
}
}
}
struct node
{
int v,w;
node(int vv,int ww)
{
v=vv;
w=ww;
}
};
vector<node> g[M*100];
void bfs(int st)
{
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
queue<int>qu;
//node tmp;
vis[st]=1;
cnt=0;
qu.push(st);
while(!qu.empty())
{
int u=qu.front();
qu.pop();
for(int i=0; i<g[u].size(); i++)
{
int v=g[u][i].v;
if(!vis[v]&&dis[v]<dis[u]+g[u][i].w)
{
vis[v]=1;
dis[v]=dis[u]+g[u][i].w;
qu.push(v);
if(cnt<dis[v])
{
cnt=dis[v];
sx=v;
}
}
}
}
}
int main()
{
int i,j,k,t;
int u,v,w;
scanf("%d",&n);
for(i=0; i<n-1; i++)
{
scanf("%d%d%d",&u,&v,&w);
g[u].push_back(node(v,w));
g[v].push_back(node(u,w));
}
sx=1;
bfs(1);
bfs(sx);
printf("%d\n",cnt*10+cnt*(cnt+1)/2);
return 0;
}
dfs:
struct node
{
int v,w;
node(int vv,int ww)
{
v=vv;
w=ww;
}
};
vector<node> g[M*100];
void dfs(int u,int sum)
{
if(cnt<sum)
{
sx=u;
cnt=sum;
}
vis[u]=1;
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i].v;
if(!vis[v])
{
vis[v]=1;
dfs(v,sum+g[u][i].w);
}
}
}
int main()
{
int i,j,k,t;
int u,v,w;
scanf("%d",&n);
for(i=0; i<n-1; i++)
{
scanf("%d%d%d",&u,&v,&w);
g[u].push_back(node(v,w));
g[v].push_back(node(u,w));
}
cnt=0;sx=1;
memset(vis,0,sizeof(vis));
dfs(1,0);
memset(vis,0,sizeof(vis));
dfs(sx,0);
printf("%d\n",cnt*10+cnt*(cnt+1)/2);
return 0;
}
扒的spfa实现:http://www.cnblogs.com/icode-girl/p/5281313.html
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <queue>
#define maxn 100010
#define inf 100000000
using
namespace
std;
int
n;
// 顶点个数
struct
Node {
int
v;
int
w;
// 存储该边权值
int
nxt;
}edge[maxn];
int
head[maxn];
int
tot;
void
addEdge(
int
u,
int
v,
int
w) {
edge[tot].v = v;
edge[tot].w = w;
edge[tot].nxt = head[u];
head[u] = tot++;
}
int
dis[maxn];
// 存储源点到每个顶点的最短距离
int
vis[maxn];
// 判断当前顶点是不是已经入队
int
spfa(
int
src) {
for
(
int
i=1; i<=n; ++i) {
dis[i] = inf;
}
dis[src] = 0;
queue<
int
> que;
vis[src] = 1;
que.push(src);
while
(!que.empty()) {
int
u = que.front();
que.pop();
vis[u] = 0;
for
(
int
i=head[u]; i!=-1; i=edge[i].nxt) {
int
v = edge[i].v;
if
(dis[v] > dis[u] + edge[i].w) {
dis[v] = dis[u] + edge[i].w;
if
(!vis[v]) {
vis[v] = 1;
que.push(v);
}
}
}
}
}
int
main() {
memset(head, -1,
sizeof
(head));
tot = 0;
while
(cin >> n) {
for
(
int
i=1; i<n; ++i) {
int
u, v, w;
cin >> u >> v >> w;
addEdge(u, v, w);
addEdge(v, u, w);
}
spfa(1);
int
ans = 0, temp;
for
(
int
i=1; i<=n; ++i) {
if
(ans < dis[i]) {
ans = dis[i];
temp = i;
}
}
spfa(temp);
for
(
int
i=1; i<=n; ++i) {
if
(ans < dis[i]) {
ans = dis[i];
}
}
temp = ans;
ans = (temp*(temp+1))/2;
ans += 10*temp;
cout << ans << endl;
}
return
0;
}