 /**//*
一棵树n<=180,树上每条边的长度都是1,若两点的距离为len,则他们通信的代价就是d[len]
d[]是给出的
可以选一些点建立Information Reform,这些点可自动获取信息,建立一个这样的点代价为k
其他没建的点就会与最近的Information Reform通信,以获取信息
求使得树上所有点都能获取信息的最小代价,以及它们各自要通信的Information Reform

不会做 .看了解题报告还是一头雾水,知道需要O(n^3)的树形dp
看别人代码的
dp[u,c]表示u的这棵子树,其中u以c为Information Reform的最小代价,但u的子树上的
其他点不一定以c为Information Reform
则dp[u,c] = cost[u,v] + ∑min{dp[v,c], dp[v,center[v]] + k}
center[u],它是使u这棵子树所有点获得信息的最小代价的Information Reform

注意的是center[u]是指使u这棵子树所有点能获得信息的最小代价,不一定是最后的答案
所以输出答案时,可以自顶向下,比如0的肯定是center[0],然后利用之前的转移
dp[u,c] = cost[u,v] + ∑min{dp[v,c], dp[v,c'] + k}
去更新子树实际的center[v]
if dp[v,center[u]] < dp[v,center[v]] + k
center[v] = c

第一次遇到这样的树形dp,在考虑某棵子树时,影响它代价的可以是整棵树(如这里可以以u子树外
的点为Information Reform) ------------------OMG
*/
#include<iostream>
#include<cstring>
#include<map>
#include<algorithm>
#include<stack>
#include<queue>
#include<cmath>
#include<string>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<set>
#include<list>
#include<numeric>
#include<cassert>
#include<ctime>
#include<bitset>

using namespace std;

const int MAXN = 200;
const int INF = 0x3f3f3f3f;

vector<int> e[MAXN];
int w[MAXN][MAXN], d[MAXN];
int center[MAXN], dp[MAXN][MAXN];
int n, k;

 void floyd() {
 for (int k = 0 ; k < n; k++) {
 for (int i = 0; i < n ; i ++) {
 if(w[i][k] == INF) {
continue;
}
 for (int j = 0 ; j < n; j++) {
 if(w[k][j] == INF) {
continue;
}
w[i][j] = min(w[i][j], w[i][k] + w[k][j]);
}
}
}
}

 void dfs(int u, int p) {
 for (vector<int>::iterator it = e[u].begin() ; it != e[u].end(); it++) {
int v = *it;
 if(v != p) {
dfs(v, u);
}
}
center[u] = 0;
 for (int f = 0; f < n ; f ++) {
dp[u][f] = d[w[u][f]];
 for (vector<int>::iterator it = e[u].begin(); it != e[u].end(); it++) {
int v = *it;
 if(v != p) {
dp[u][f] += min(dp[v][f], dp[v][center[v]] + k);
}
}
 if(dp[u][f] < dp[u][center[u]]) {
center[u] = f;
}
}
}

 void retrieve(int u, int p) {
 for (vector<int>::iterator it = e[u].begin() ; it != e[u].end(); it++) {
int v = *it;
 if(v != p) {
int f = center[u];
 if(dp[v][f] < dp[v][center[v]] + k) {
center[v] = f;
}
retrieve(v, u);
}
}
}

int main()
  {
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
#endif
 for (; ~scanf("%d%d", &n, &k); ) {
fill(w[0], w[n], INF);
 for (int i = 0 ; i < n ; i ++ ) {
e[i].clear();
w[i][i] = 0;
}
 for (int i = 1 ; i < n ; i ++) {
scanf("%d", &d[i]);
}
 for (int i = 1,u,v; i <n; i++) {
scanf("%d%d", &u, &v);
u--;
v--;
e[u].push_back(v);
e[v].push_back(u);
w[u][v] = w[v][u] = 1;
}
floyd();
dfs(0,0);
retrieve(0,0);
printf("%d\n", dp[0][center[0]] + k);//还要加上k
 for (int i = 0 ; i < n ; i ++) {
 if (i >0) {
putchar(' ');
}
printf("%d", center[i] + 1);
}
puts("");
}
return 0;
}
|
|
常用链接
随笔分类
Links
搜索
最新评论

|
|