zoukankan      html  css  js  c++  java
  • AcWing 1141. 局域网  图论

    地址 https://www.acwing.com/problem/content/description/1143/

    某个局域网内有 n 台计算机和 k 条 双向 网线,计算机的编号是 1∼n。由于搭建局域网时工作人员的疏忽,现在局域网内的连接形成了回路,我们知道如果局域网形成回路那么数据将不停的在回路内传输,造成网络卡的现象。
    
    注意:
    
    对于某一个连接,虽然它是双向的,但我们不将其当做回路。本题中所描述的回路至少要包含两条不同的连接。
    两台计算机之间最多只会存在一条连接。
    不存在一条连接,它所连接的两端是同一台计算机。
    因为连接计算机的网线本身不同,所以有一些连线不是很畅通,我们用 f(i,j) 表示 i,j 之间连接的畅通程度,f(i,j) 值越小表示 i,j 之间连接越通畅。
    
    现在我们需要解决回路问题,我们将除去一些连线,使得网络中没有回路且不影响连通性(即如果之前某两个点是连通的,去完之后也必须是连通的),并且被除去网线的 Σf(i,j) 最大,请求出这个最大值。
    
    输入格式
    第一行两个正整数 n,k。
    
    接下来的 k 行每行三个正整数 i,j,m 表示 i,j 两台计算机之间有网线联通,通畅程度为 m。
    
    输出格式
    一个正整数,表示被除去网线的 Σf(i,j) 的最大值。
    
    数据范围
    1≤n≤100
    0≤k≤200
    1≤f(i,j)≤1000
    输入样例:
    5 5
    1 2 8
    1 3 1
    1 5 3
    2 4 5
    3 4 2
    输出样例:
    8

    解答

    算法1
    floyd算法,似乎只要跑一遍最小树,将最小树的权边计算出来,和总权值的差就是要去掉的边的权值

    但是经过群友提示,这个图不是连通的,跑prim一遍得不到所有点的最小树。

    我之前没看出来,局域网的电脑还带回路,还有不连通的局域网吗??

    那么稍微修改下prim
    如果计算两点之间距离是无穷大 也就是不连通,那么不计算两点之间的权边,继续congtinue
    本次prim完成后 找到那些st[0]为零 也就是标记还没在树的点 继续进行prim

    最后所有的点 都生成了最小树(可能不止一棵)
    和total的差值就是答案

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <memory.h>
    
    using namespace std;
    
    const int N = 510, INF = 0x3f3f3f3f;
    
    int n, m;
    
    int g[N][N];
    int dist[N];
    bool st[N];
    
    
    int prim(int point)
    {
        memset(dist, 0x3f, sizeof dist);
    
        int res = 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) continue;
            if (i) res += dist[t];
            st[t] = true;
    
            for (int j = 1; j <= n; j++) dist[j] = min(dist[j],g[t][j]);
        }
    
        return res;
    }
    
    int main()
    {
        cin >> n >> m;
        memset(g, 0x3f, sizeof g);
        int total;
        while (m--) {
            int a, b, c;
            cin >> a >> b >> c;
            g[a][b] = g[b][a] = min(g[a][b], c);
            total += c;
        }
    
        for (int i = 1; i <= n; i++) {
            if (st[i] == 0)
                total -= prim(i);
        }
    
        cout << total << endl;
    
    
        return 0;
    }
    
    
    
    作者:itdef
    链接:https://www.acwing.com/file_system/file/content/whole/index/content/1056648/
    来源:AcWing
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    成长
    mui组件通用CSS类
    CSS推荐的类名
    必须认识的http请求包
    Bootstrap技术: 如何给nav导航组件的tab页增加关闭按钮以及动态的添加和关闭tab页
    bootstrap 关闭tabs
    typescirpt 知识点
    手动使用gulp4.0配合rollup搭建typescript 写一个自己的一个开源库(起步 构建自动化处理,热更新浏览器)
    Wuss Weapp 一款高质量,组件齐全,高自定义的微信小程序 UI 组件库
    wussUI v1.0.0小程序UI组件库 第一期开发已完成
  • 原文地址:https://www.cnblogs.com/itdef/p/13187104.html
Copyright © 2011-2022 走看看