一.题目链接:
POJ-3585
二.题目大意:
给出一颗无根树,每条边有权值 w[i]
当选择一点为根时,从该点灌水,要求每条路上的水都不能溢出
现可以任意一点为根,求最大灌水量.
三.分析:
好像是个模板题....
四.代码实现:
#include <cstdio>
#include <algorithm>
using namespace std;
const int M = (int)2e5;
const int inf = 0x3f3f3f3f;
int cnt;
int head[M + 5];
struct node
{
int v, w, nx;
}Edge[M * 2 + 5];
int in[M + 5];
int d[M + 5];
int f[M + 5];
void init(int n)
{
cnt = 0;
for(int i = 1; i <= n; ++i)
{
in[i] = 0;
head[i] = -1;
}
}
void add(int u, int v, int w)
{
Edge[cnt].v = v;
Edge[cnt].w = w;
Edge[cnt].nx = head[u];
head[u] = cnt++;
}
int dfs_d(int u, int fa)
{
d[u] = 0;
for(int i = head[u]; ~i; i = Edge[i].nx)
{
int v = Edge[i].v;
if(v == fa) continue;
d[u] += min(Edge[i].w, dfs_d(v, u));
}
if(in[u] == 1)
return Edge[head[u]].w;
else
return d[u];
}
void dfs_f(int u, int fa)
{
for(int i = head[u]; ~i; i = Edge[i].nx)
{
int v = Edge[i].v;
if(v == fa) continue;
f[v] = d[v] + min(Edge[i].w, f[u] - min(Edge[i].w, d[v] ? d[v] : inf));
if(in[u] == 1)
f[v] += Edge[i].w;
dfs_f(v, u);
}
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int n;
scanf("%d", &n);
init(n);
for(int i = 0, u, v, w; i < n - 1; ++i)
{
scanf("%d %d %d", &u, &v, &w);
add(u, v, w), add(v, u, w);
in[u]++, in[v]++;
}
dfs_d(1, 0);
f[1] = d[1];
dfs_f(1, 0);
int ans = 0;
for(int i = 1; i <= n; ++i)
ans = max(ans, f[i]);
printf("%d\n", ans);
}
return 0;
}