AcWing
  • 首页
  • 课程
  • 题库
  • 更多
    • 竞赛
    • 题解
    • 分享
    • 问答
    • 应用
    • 校园
  • 关闭
    历史记录
    清除记录
    猜你想搜
    AcWing热点
  • App
  • 登录/注册

AcWing 1140. $\Large\color{blue}{【算法提高课】最短网络(\text{Kruskal 或 prim})}$    原题链接    简单

作者: 作者的头像   incra ,  2022-06-11 07:32:17 ,  所有人可见 ,  阅读 639


9


<—点个赞吧QwQ

宣传一下算法提高课整理{:target=”_blank”}

农夫约翰被选为他们镇的镇长!

他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场。

约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。

约翰的农场的编号是1,其他农场的编号是 $2 \\sim n$。

为了使花费最少,他希望用于连接所有的农场的光纤总长度尽可能短。

你将得到一份各农场之间连接距离的列表,你必须找出能连接所有农场并使所用光纤最短的方案。

输入格式

第一行包含一个整数 $n$,表示农场个数。

接下来 $n$ 行,每行包含 $n$ 个整数,输入一个对角线上全是0的对称矩阵。
其中第 $x+1$ 行 $y$ 列的整数表示连接农场 $x$ 和农场 $y$ 所需要的光纤长度。

输出格式

输出一个整数,表示所需的最小光纤长度。

数据范围

$3 \\le n \\le 100$
每两个农场间的距离均是非负整数且不超过100000。

输入样例:

4
0  4  9  21
4  0  8  17
9  8  0  16
21 17 16  0

输出样例:

28

代码1(prim)

#include <iostream>
#include <cstring>
using namespace std;
const int N = 110,INF = 0x3f3f3f3f;
int n;
int g[N][N];
int dist[N];
bool st[N];
int prim () {
    memset (dist,0x3f,sizeof (dist));
    int ans = 0;
    for (int i = 0;i < n;i++) {
        int t = -1;
        for (int j = 1;j <= n;j++) {
            if (!st[j] && (t == -1 || dist[t] > dist[j])) t = j;
        }
        if (i && dist[t] == INF) return INF;
        if (i) ans += dist[t];
        st[t] = true;
        for (int j = 1;j <= n;j++) dist[j] = min (dist[j],g[t][j]);
    }
    return ans;
}
int main () {
    cin >> n;
    for (int i = 1;i <= n;i++) {
        for (int j = 1;j <= n;j++) {
            cin >> g[i][j];
        }
    }
    cout << prim () << endl;
    return 0;
}

代码2(kruskal)

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 110,M = 10010;
struct Edge {
    int a,b,w;
}edges[M];
int n,cnt = 0;
int p[N];
int find (int x) {
    if (p[x] != x) p[x] = find (p[x]);
    return p[x];
}
int kruskal () {
    sort (edges+1,edges+1+cnt,[](Edge a,Edge b) {
        return a.w < b.w;
    });
    int ans = 0;
    for (int i = 1;i <= cnt;i++) {
        auto [a,b,w] = edges[i];
        a = find (a),b = find (b);
        if (a != b) {
            p[a] = b;
            ans += w;
        }
    }
    return ans;
}
int main () {
    cin >> n;
    for (int i = 1;i <= n;i++) p[i] = i;
    for (int i = 1;i <= n;i++) {
        for (int j = 1;j <= n;j++) {
            int x;
            cin >> x;
            edges[++cnt] = {i,j,x};
        }
    }
    cout << kruskal () << endl;
    return 0;
}

0 评论

App 内打开
你确定删除吗?
1024
x

© 2018-2025 AcWing 版权所有  |  京ICP备2021015969号-2
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标 qq图标
请输入绑定的邮箱地址
请输入注册信息