Description
Country Z has N cities, which are numbered from 1 to N. Cities are connected by highways, and there is exact one path between two different cities. Recently country Z often caught fire, so the government decided to build some firehouses in some cities. Build a firehouse in city K cost W(K). W for different cities may be different. If there is not firehouse in city K, the distance between it and the nearest city which has a firehouse, can’t be more than D(K). D for different cities also may be different. To save money, the government wants you to calculate the minimum cost to build firehouses.
Input
The first line of input contains a single integer T representing the number of test cases. The following T blocks each represents a test case.
The first line of each block contains an integer N (1 < N <= 1000). The second line contains N numbers separated by one or more blanks. The I-th number means W(I) (0 < W(I) <= 10000). The third line contains N numbers separated by one or more blanks. The I-th number means D(I) (0 <= D(I) <= 10000). The following N-1 lines each contains three integers u, v, L (1 <= u, v <= N,0 < L <= 1000), which means there is a highway between city u and v of length L.
The first line of each block contains an integer N (1 < N <= 1000). The second line contains N numbers separated by one or more blanks. The I-th number means W(I) (0 < W(I) <= 10000). The third line contains N numbers separated by one or more blanks. The I-th number means D(I) (0 <= D(I) <= 10000). The following N-1 lines each contains three integers u, v, L (1 <= u, v <= N,0 < L <= 1000), which means there is a highway between city u and v of length L.
Output
For each test case output the minimum cost on a single line.
Sample Input
5 5 1 1 1 1 1 1 1 1 1 1 1 2 1 2 3 1 3 4 1 4 5 1 5 1 1 1 1 1 2 1 1 1 2 1 2 1 2 3 1 3 4 1 4 5 1 5 1 1 3 1 1 2 1 1 1 2 1 2 1 2 3 1 3 4 1 4 5 1 4 2 1 1 1 3 4 3 2 1 2 3 1 3 3 1 4 2 4 4 1 1 1 3 4 3 2 1 2 3 1 3 3 1 4 2
Sample Output
2 1 2 2 3
Source
POJ Monthly,Lou Tiancheng
lyd课件上的题,(((φ(◎ロ◎;)φ)))看不懂啊。一看是楼教出的题,也就。。
查题解时发现是陈启峰论文里的,写得很不错。附链接——https://wenku.baidu.com/view/82124f74f242336c1eb95e44.html
dp[i][j]表示以i为根的子树里修建一些消防站,并在节点j处修建一消防站,i的负责站必须是j;
best[i]:表示表示以i为根的子树的所有节点都有负责站的最小花费。
dist[i]:表示i到x的距离(每换换一个节点,都要再求一次dist[])。
状态状态转移方程:dp[i][j]=w[j]+sum(min(best[y],dp[y][j]-w[i]))(y是i的所有孩子);
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int N=1005;
int T,n,cnt,w[N],d[N],dp[N][N],f[N],dis[N],hd[N];
struct node
{
int to,nxt,l;
}v[2*N];
void addedge(int x,int y,int z)
{
++cnt;
v[cnt].to=y;
v[cnt].l=z;
v[cnt].nxt=hd[x];
hd[x]=cnt;
}
void dist(int u)
{
for(int i=hd[u];i;i=v[i].nxt)
if(dis[v[i].to]==-1)
{
dis[v[i].to]=dis[u]+v[i].l;
dist(v[i].to);
}
}
void dfs(int u,int fa)
{
for(int i=hd[u];i;i=v[i].nxt)
if(v[i].to!=fa)
dfs(v[i].to,u);
memset(dis,-1,sizeof(dis));
dis[u]=0;
f[u]=1e9+7;
dist(u);
for(int i=1;i<=n;i++)
{
if(dis[i]>d[u])
dp[u][i]=1e9+7;
else
{
dp[u][i]=w[i];
for(int j=hd[u];j;j=v[j].nxt)
if(v[j].to!=fa)
dp[u][i]+=min(f[v[j].to],dp[v[j].to][i]-w[i]);
f[u]=min(f[u],dp[u][i]);
}
}
}
int main()
{
scanf("%d",&T);
while(T--)
{
cnt=0;
memset(hd,0,sizeof(hd));
memset(f,0x3f,sizeof(f));
memset(dp,0x3f,sizeof(dp));
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&w[i]);
for(int i=1;i<=n;i++)
scanf("%d",&d[i]);
for(int i=1;i<=n-1;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
addedge(x,y,z);
addedge(y,x,z);
}
dfs(1,0);
printf("%d\n",f[1]);
}
return 0;
}