列表

详情


NC50363. 构造完全图

描述

对于完全图G,若有且仅有一棵最小生成树为T,则称完全图G是树T扩展出的。
给你一棵树T,找出T能扩展出的边权和最小的完全图G。

输入描述

第一行N表示树T的点数;
接下来N-1行三个整数S_i,T_i,D_i;描述一条边(S_i,T_i)权值为D_i
保证输入数据构成一棵树。

输出描述

输出仅一个数,表示最小的完全图$G$的边权和。

示例1

输入:

4  
1 2 1  
1 3 1  
1 4 2  

输出:

12

说明:

添加D(2,3)=2,D(3,4)=3,D(2,4)=3即可。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 144ms, 内存消耗: 4376K, 提交时间: 2019-12-22 15:31:44

#include<bits/stdc++.h>
using namespace std;

const int MAXN = 1e5+7;
int p[MAXN];
long long cnt[MAXN];
int find(int x) {
  if (p[x] == x) return x;
  return p[x] = find(p[x]);
}

void init() {
  for (int i = 0; i < MAXN; i++) p[i] = i, cnt[i] = 1;
}

struct Edge{
  int u, v, w;
};

int main() {
  init();
  int N; cin >> N;
  long long tot = 0;
  vector<Edge> edges(N -1 );
  for (auto &e: edges) cin >> e.u >> e.v >> e.w;
  sort(edges.begin(), edges.end(), [](const Edge &a, const Edge &b) {
    return a.w < b.w;
  });
  for (auto &e: edges) {
    int pu = find(e.u), pv = find(e.v);
    tot += (cnt[pu] * cnt[pv] - 1ll) * (e.w + 1ll) + e.w;
    cnt[pu] += cnt[pv];
    p[pv] = pu;
  }
  cout << tot << endl;
}

C++(clang++11) 解法, 执行用时: 51ms, 内存消耗: 4252K, 提交时间: 2021-05-09 13:54:03

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n;
ll ans;
ll f[100010],cnt[100010];
struct T{
    ll u,v,w;
}t[100010];
ll fa(ll x){
    if(f[x]!=x) return fa(f[x]);
    else return f[x];
}
bool cmp(T x,T y){ return x.w<y.w;}
int main()
{
    cin>>n;
    for(ll i=1;i<=n-1;i++){
        scanf("%d%d%d",&t[i].u,&t[i].v,&t[i].w);
        ans+=t[i].w;
    }
    for(ll i=1;i<=n;i++) f[i]=i,cnt[i]=1;
    sort(t+1,t+n,cmp);
    for(ll i=1;i<n;i++){
        ll r1=fa(t[i].u);
        ll r2=fa(t[i].v);
        if(r1!=r2){
            ans+=(cnt[r1]*cnt[r2]-1)*(t[i].w+1);
            f[r2]=r1;
            cnt[r1]+=cnt[r2];
        }
    }
    cout<<ans;
}

上一题