当前位置:首页 > 技术 > 正文内容

使用Prim算法解决局域网回路问题

访客 技术 2026年6月29日 1

题目链接:洛谷 P2820 局域网

题目背景

某局域网中有n(n≤100)台计算机,由于搭建时的疏忽,网络连接形成了回路。这种情况下数据会在回路中不断传输,导致网络卡顿。计算机之间的网线连接通畅程度不同,我们用f(i,j)表示i,j之间的通畅程度,值越小表示连接越通畅,0表示无连接。

题目描述

需要移除部分连线,消除网络中的回路,同时使被移除网线的Σf(i,j)总和最大。请计算这个最大值。

输入输出格式

输入格式:

第一行:两个正整数n和k
接下来k行:每行三个正整数i、j、m,表示i和j之间有网线连接,通畅程度为m。

输出格式:

一个正整数,表示被移除网线的Σf(i,j)的最大值。

输入输出样例

输入样例:

5 5
1 2 8
1 3 1
1 5 3
2 4 5
3 4 2

输出样例:

8

说明

f(i,j)≤1000

解题思路

这个问题本质上是在求图的最小生成树。我们需要理解以下概念:

相关概念:

  • 生成树:在一个图中连接所有n个节点的n-1条边形成的树结构
  • 最小生成树:在所有可能的生成树中,边权总和最小的树

算法选择:

可以使用Prim算法或Kruskal算法解决此问题。本文将重点介绍Prim算法的实现。

Prim算法原理:

Prim算法采用"红点-白点"思想:初始时,选择一个节点作为红点(已加入生成树),其余节点为白点。每次循环找出距离红点集合最近的白点,将其变为红点,并用该点更新其他白点到红点集合的距离。重复此过程直到所有节点都成为红点。

对于本题,被移除网线的最大总和 = 原图所有边权总和 - 最小生成树的边权总和。

代码实现


#include <iostream>
#include <cstring>
#include <climits>
using namespace std;

const int MAXN = 105;
int network[MAXN][MAXN];  // 存储网络连接的邻接矩阵
int dist[MAXN];           // 存储每个节点到生成树的最短距离
bool inTree[MAXN];        // 标记节点是否已在生成树中
int nodeCount, connectionCount;
int totalWeight = 0;      // 原图总权重
int mstWeight = 0;        // 最小生成树权重

int main() {
    cin >> nodeCount >> connectionCount;
    
    // 初始化邻接矩阵
    memset(network, 0, sizeof(network));
    
    // 读取输入并计算总权重
    for (int i = 0; i < connectionCount; i++) {
        int u, v, w;
        cin >> u >> v >> w;
        network[u][v] = network[v][u] = w;
        totalWeight += w;
    }
    
    // 初始化距离数组和标记数组
    memset(dist, 0x7f, sizeof(dist));
    memset(inTree, false, sizeof(inTree));
    
    // 从节点1开始构建最小生成树
    dist[1] = 0;
    
    for (int i = 1; i <= nodeCount; i++) {
        // 找到距离生成树最近的节点
        int nearest = 0;
        for (int j = 1; j <= nodeCount; j++) {
            if (!inTree[j] && ((dist[j] < dist[nearest]) || nearest == 0)) {
                nearest = j;
            }
        }
        
        // 将该节点加入生成树
        inTree[nearest] = true;
        mstWeight += dist[nearest];
        
        // 更新其他节点到生成树的距离
        for (int j = 1; j <= nodeCount; j++) {
            if (network[nearest][j] && !inTree[j]) {
                dist[j] = min(dist[j], network[nearest][j]);
            }
        }
    }
    
    // 计算并输出结果
    cout << totalWeight - mstWeight << endl;
    
    return 0;
}

此代码实现了Prim算法来解决局域网回路问题。通过计算原图总权重与最小生成树权重的差值,得到需要移除的网线最大总和。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。