题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6201
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)
Problem Description
Kelukin is a businessman. Every day, he travels around cities to do some business. On August 17th, in memory of a great man, citizens will read a book named "the Man Who Changed China". Of course, Kelukin wouldn't miss this chance to make money, but he doesn't have this book. So he has to choose two city to buy and sell.
As we know, the price of this book was different in each city. It is a_i yuan in it city. Kelukin will take taxi, whose price is 1yuan per km and this fare cannot be ignored.
There are n-1 roads connecting n cities. Kelukin can choose any city to start his travel. He want to know the maximum money he can get.
Input
The first line contains an integer () , the number of test cases.
For each test case:
first line contains an integer () means the number of cities;
second line contains numbers, the number means the prices in city; ()
then follows lines, each contains three numbers , and which means there exists a road between and , the distance is ().
Output
For each test case, output a single number in a line: the maximum money he can get.
Sample Input
1
4
10 40 15 30
1 2 30
1 3 2
3 4 10
Sample Output
8
Problem solving report:
Description: n个点,n-1条边,每个点有点权代表书的价格,边权代表路上的消耗,一个人选择两个城市,在一个城市买书,到另一个城市去卖书,输出他最多能赚多少钱?
Problem solving: 我们建立一个源点0,使得源点连入各个点,花费是-w[i],表示我们想要从这个点作为出发点的花费,然后再建立一个汇点n+1,让各个点连入这个点,花费是w[i],表示我们想要从这个点作为终点的利润。中间边都要建成负权值,跑一条最长路即可。
Accepted Code:
/*
* @Author: lzyws739307453
* @Language: C++
*/
#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const int MAXN = 1000005;
int cnt, n;
int f[MAXN], dis[MAXN];
bool vis[MAXN];
struct edge {
int u, v, w;
edge() {}
edge(int u, int v, int w) : u(u), v(v), w(w) {}
} e[MAXN];
void Add_edge(int u, int v, int w) {
e[++cnt] = edge(f[u], v, w);
f[u] = cnt;
}
void init() {
cnt = 0;
memset(f, -1, sizeof(f));
memset(vis, 0, sizeof(vis));
memset(dis, -inf, sizeof(dis));
}
void Spfa(int s) {
queue <int> Q;
Q.push(s);
vis[s] = true;
dis[s] = 0;
while (!Q.empty()) {
int u = Q.front();
Q.pop();
vis[u] = false;
for (int i = f[u]; ~i; i = e[i].u) {
int v = e[i].v;
if (dis[v] < dis[u] + e[i].w) {
dis[v] = dis[u] + e[i].w;
if (!vis[v]) {
vis[v] = true;
Q.push(v);
}
}
}
}
}
int main() {
int t, w;
scanf("%d", &t);
while (t--) {
init();
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &w);
Add_edge(0, i, -w);
Add_edge(i, n + 1, w);
}
for (int i = 0; i < n - 1; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
Add_edge(u, v, -w);
Add_edge(v, u, -w);
}
Spfa(0);
printf("%d\n", dis[n + 1]);
}
return 0;
}