题目链接:​​http://acm.hdu.edu.cn/showproblem.php?pid=6201​​​
题意:有n座城市,有n-1条道路连接这n个城市,每条道路有长度,,表示这个人从x城市到y城市需要的花费是z元每个城市有一个值,表示在这个城市买书和卖书的价格,有一个人必须从这n个城市里选两个城市出来做生意,现在问你,这个人最多能赚多少钱
解析:我的方法是,类似树的直径的做法,从任意一个点开始bfs,找到利润最大的那个点,然后从这个点在bfs一遍,去找另一个利润最大的点,接下来就是考虑如果使得搜到的每个值的价值一定是当前的最小利润呢,这个应该是类似dp的一个东西吧,就是这个节点的利润,要么是父节点直接到这点的利润,要么就是父节点之前的某个节点到这个点利润,同时这个点也应该是到父节点的利润是最小的,然后这样取一下最小值存起来,感觉很难表述,看代码吧

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+100;
const int inf = 0x7fffffff;
struct node
{
int v,c;
node() {}
node(int _v,int _c)
{
v = _v;
c = _c;
}
}value[maxn];
vector<node>G[maxn];
int a[maxn];
int vis[maxn];
int dis[maxn];
void bfs(int s)
{
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
vis[s] = 1;
dis[s] = 0;
value[s].v = s;
value[s].c = 0;
queue<int>q;
q.push(s);
while(!q.empty())
{
int u = q.front();
q.pop();
for(int i=0;i<(int)G[u].size();i++)
{
node v = G[u][i];
if(vis[v.v]) continue;
vis[v.v] = 1;
dis[v.v] = dis[u]+v.c;
if(abs(a[u]-a[v.v])-v.c>abs(a[value[u].v]-a[v.v])-dis[v.v]+dis[value[u].v])
{
value[v.v].v = u;
value[v.v].c = abs(a[u]-a[v.v])-v.c;
}
else
{
value[v.v].v = value[u].v;
value[v.v].c = abs(a[value[u].v]-a[v.v])-dis[v.v]+dis[value[u].v];
}
q.push(v.v);
}
}
}
int main(void)
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
G[i].clear();
}
for(int i=1;i<n;i++)
{
int x,y,c;
scanf("%d %d %d",&x,&y,&c);
G[x].push_back(node(y,c));
G[y].push_back(node(x,c));
}
bfs(1);
int ans = -inf,ansi;
for(int i=1;i<=n;i++)
{
if(ans<value[i].c && i!=1)
{
ans = dis[i];
ansi = i;
}
}
bfs(ansi);
ans = -inf;
for(int i=1;i<=n;i++)
{
if(i==ansi) continue;
ans = max(ans,value[i].c);
}
printf("%d\n",ans);
}
return 0;
}
/*
5
10 10 50 100 10
1 2 10
1 3 10
1 4 1000
4 5 0
*/