目的:求出树的各边长度
条件:每个节点之间最短路、整个图中不存在负边
我们可以每一次把一个点加入树内,求出这个点和已经构建好的树的边的长度;
这个长度抽象理解一下就是(dis[i][j]+dis[i][root]-dis[root][j])/2
为什么?因为上面的式子中这条边刚好遍历了两次;
然后答案加上这条边的长度就好了;
#include <bits/stdc++.h> using namespace std; int a[100][100]; int main() { int n; scanf("%d",&n); while(n){ for(int i=1;i<=n;i++){ for(int j=i+1;j<=n;j++){ scanf("%d",&a[i][j]); a[j][i]=a[i][j]; } } int root=1; int ans=0; for(int i=1;i<=n;i++){ int len=INT_MAX; for(int j=1;j<i;j++){ len=min(len,(a[i][j]+a[i][root]-a[root][j])/2); } if(i!=1) ans+=len; } printf("%d ",ans); scanf("%d",&n); } }