AcWing 1138:城市公交网建设问题 ← Kruskal算法模板题

【题目来源】
https://www.acwing.com/problem/content/1140/

【题目来源】
有一张城市地图,图中的顶点为城市,编号为 1∼n,无向边 代表两个城市间的连通关系,边上的权值为在这两个城市之间修建高速公路的造价,研究后发现,这个地图有一个特点,即任何一对城市都是连通的。
现在的问题是,要修建若干高速公路把所有城市联系起来,问如何设计可使得工程的总造价最少?

【输入格式】
第一行包含两个整数 n 和 e,分别表示城市个数和无向边个数。
接下来 e 行,每行包含三个整数 i,j,w,表示在城市 i 和城市 j 之间修建公路的造价为 w。
城市
编号从 1 开始

【输出格式】
共 n−1 行,每行为两个城市的编号,表明在这两个城市间建一条高速公路。
本题
答案不一定唯一,输出任意一种最优方案即可,方案中边和点的顺序可以任意选择。

【数据范围】
1≤n≤100,
1≤e≤1000,
1≤w≤10000
数据保证
不含重边自环

【输入样例】
5 8
1 2 2
2 5 9
5 4 7
4 1 10
1 3 12
4 3 6
5 3 3
2 3 8

【输出样例】
1 2
2 3
3 4
3 5

【算法分析】
最小生成树问题,在结点数量较多时,适合采用 Kruskal 算法求解。
●​​​​​​​ Kruskal算法模板题详见:

https://blog.csdn.net/hnjzsyjyj/article/details/139652267
https://blog.csdn.net/hnjzsyjyj/article/details/139606429
● 并查集
https://blog.csdn.net/hnjzsyjyj/article/details/126455868
https://blog.csdn.net/hnjzsyjyj/article/details/117869180

【算法代码】

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

const int maxn=1e4+5;
int pre[maxn];
int n,m;

struct edge {
	int u,v;
	int cost;
} e[maxn*maxn]; //keypoint

bool cmp(edge x, edge y) {
    return x.cost<y.cost;
}

int find(int x) { //DSU's find
    if(x!=pre[x]) pre[x]=find(pre[x]);
    return pre[x];
}

int main() {
    cin>>n>>m;
    for(int i=0; i<m; i++) {
        int u,v,cost;
        cin>>u>>v>>cost;
        e[i]= {u,v,cost};
    }

    for(int i=1; i<=n; i++) pre[i]=i;

    sort(e,e+m,cmp);

    for(int i=0; i<m; i++) {
        int fx=find(e[i].u);
        int fy=find(e[i].v);
        if(fx!=fy) {
            pre[fy]=fx;
            cout<<e[i].u<<" "<<e[i].v<<endl;
        }
    }

    return 0;
}

/*
in:
5 8
1 2 2
2 5 9
5 4 7
4 1 10
1 3 12
4 3 6
5 3 3
2 3 8

out:
1 2
2 3
3 4
3 5
*/





【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/139652267
https://www.acwing.com/solution/content/78311/
https://blog.csdn.net/hnjzsyjyj/article/details/139650721



 

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值