修建公路1(Prim、Kruskal)

4.修建公路1 - 蓝桥云课

 

 

题目描述

LL 城一共有 NN 个小区。

小明是城市建设的规划者,他计划在城市修 MM 条路,每修建一条路都要支付工人们相应的工钱(需要支付的工钱 == 路的长度)。

然而小明所拿到的经费并不够支付修建 MM 条路的工钱,于是迫于无奈,他只能将计划改变为修建若干条路,使得 NN 个小区之间两两联通。

小明希望尽量剩下更多的经费投入到别的项目中,因此请你通过程序帮他计算出完成计划所需的最低开销。

输入描述

输入第一行包含三个正整数 N,MN,M。

第 22 到 M+1M+1 行每行包含三个正整数 u,v,wu,v,w,表示 u↔vu↔v 之间存在一条距离为 ww 的路。

1≤N≤1051≤N≤105,0≤m≤3×1050≤m≤3×105,1≤ui,vi≤N1≤ui​,vi​≤N,0≤wi≤1090≤wi​≤109。

输出描述

输出占一行,包含一个整数,表示完成计划所需的最低开销。

若无法完成计划,则输出 −1−1。

输入输出样例

示例 1

输入

5 6
1 2 2
1 3 7
1 4 6
2 3 1
3 4 3
3 5 2

输出

8

 本人使用Kruskal算法

// Problem: 2. 修建公路1
// Contest: Lanqiao
// URL:
// https://www.lanqiao.cn/problems/1124/learning/?page=1&first_category_id=1&second_category_id=8&status=1
// Memory Limit: 256 MB
// Time Limit: 3000 ms
//
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>

using namespace std;

#define endl '\n'
#define int long long
using u32 = unsigned;
using i64 = long long;
using u64 = unsigned long long;
using PII = pair<int, int>;

const int N = 3e5 + 5;

int p[N];
struct E {
  int u, v, w;
  bool operator<(E a) { return w < a.w; }
} edges[N];
void init(int n) {
  for (int i = 1; i <= n; i++) {
    p[i] = i;
  }
}
int find(int x) {
  if (p[x] != x) p[x] = find(p[x]);
  return p[x];
}
bool merge(int x, int y) {
  if (find(x) != find(y)) {
    p[find(x)] = find(y);
    return true;
  }
  return false;
}

void solve() {
  int n, m;
  cin >> n >> m;

  int total = 0, cnt = 0;
  int u, v, w;
  for (int i = 0; i < m; i++) {
    cin >> u >> v >> w;
    edges[i] = E{u, v, w};
  }
  init(n);
  sort(edges, edges + m);
  for (int i = 0; i < m; i++) {
    if (merge(edges[i].u, edges[i].v)) {
      total += edges[i].w;
      cnt++;
    }
    if (cnt == n - 1) {
      break;
      
    }
  }
  if (cnt == n - 1) {
    cout << total;
    return;
  }
  cout << -1;
}

signed main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);

  solve();

  return 0;
}

/*
 *                        _oo0oo_
 *                       o8888888o
 *                       88" . "88
 *                       (| -_- |)
 *                       0\  =  /0
 *                     ___/`---'\___
 *                   .' \\|     |// '.
 *                  / \\|||  :  |||// \
 *                 / _||||| -:- |||||- \
 *                |   | \\\  - /// |   |
 *                | \_|  ''\---/''  |_/ |
 *                \  .-\__  '-'  ___/-. /
 *              ___'. .'  /--.--\  `. .'___
 *           ."" '<  `.___\_<|>_/___.' >' "".
 *          | | :  `- \`.;`\ _ /`;.`/ - ` : | |
 *          \  \ `_.   \_ __\ /__ _/   .-` /  /
 *      =====`-.____`.___ \_____/___.-`___.-'=====
 *                        `=---='
 *
 *
 *      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *            佛祖保佑       永不宕机     永无BUG
 */

prim算法与dijkstra算法类似,下次遇到了再写 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值