题解:
题目给出了n个点在图上的最短路径矩阵,要求构造一棵树,使得这n个点都为叶子节点,并且满足最短路径矩阵,求该树的重量即树边权值和。
首先假设已知树T为当前i个节点的解,1为root,那么1-2,1-3….1-i可以的路径可以表示出该树的所有路径,所以只需枚举i+1 与2,3,4….i的LCA(最近公共祖先),根据 d[1][i] + d[j][i] = d[1][j] + 2Li (j: 2 - i )算出i+1到LCA的距离Li,取一个最小值加到ans上,然后将节点i+1加入树T. 具体证明可以看看洛克后的题解版(反正我没看太懂~V~)
AC code
#include <bits/stdc++.h>
using namespace std;
const int maxn = 30 + 10;
const int INF = 0x3f3f3f3f;
int d[maxn][maxn];
int main()
{
int n;
while(scanf("%d",&n) && n)
{
for(int i = 1; i <= n; i++)
for(int j = i+1; j <= n; j++)
{
scanf("%d",&d[i][j]);
d[j][i] = d[i][j];
}
int ans = d[1][2];
for(int i = 3; i <= n; i++)
{
int t = INF;
for(int j = 2; j < i; j++)
t = min(t,(d[1][i] + d[j][i] - d[1][j])/2);
ans += t;
}
printf("%d\n",ans);
}
return 0;
}
本文解析了洛谷P1268树的重量问题,通过给出的n个点间的最短路径矩阵,构造一棵树使得这些点成为叶子节点,并满足最短路径条件。详细介绍了如何通过枚举新增节点与已有节点之间的最近公共祖先来计算树的总边权。
1万+

被折叠的 条评论
为什么被折叠?



