zoukankan      html  css  js  c++  java
  • 【USACO3.1.1】Agri-Net最短网络

    问题描述

    农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场。当然,他需要你的帮助。约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。为了使花费最少,他想铺设最短的光纤去连接所有的农场。你将得到一份各农场之间连接费用的列表,你必须找出能连接所有农场并所用光纤最短的方案。每两个农场间的距离不会超过100000 
     

    输入格式

    第一行: 农场的个数,N(3<=N<=100)。 

    第二行..结尾: 接下来的行包含了一个N*N的矩阵,表示每个农场之间的距离。理论上,他们是N行,每行由N个用空格分隔的数组成,实际上,他们每行限制在80个字符以内,因此,某些行会紧接着另一些行。当然,对角线将会是0,因为线路从第i个农场到它本身的距离在本题中没有意义。 
     

    输出格式

    只有一个输出,是连接到每个农场的光纤的最小长度和。

    样例输入

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

    样例输出

    28

    此题其实比较简单,我们可以把镇子看成一幅图,在其中,村子为点,网线为点。

    我们需要做的,就是在这幅图中,保留一些点,做为光纤,使每个村子有且仅有一条线路与另一个村子相连。

    很显然,这符合一颗树的性质。所以,我们只要使得生成的树最小(边之和最小)就行了。

    上面一通解释,其实就是说明此题应使用最小生成树。

    在这里。我们暂且使用Kruskal算法。

    其算法主题思想为:

    1.每次选不属于同一生成树的且权值最小的边的顶点,将边加入生成树,并将所在的2个生成树合并,直到只剩一个生成树

     2.排序使用sort

    3.检查是否在同一生成树用并查集

    代码见下,详细请见:

    https://blog.csdn.net/akidlizijia/article/details/93914185

    #include <bits/stdc++.h>
     
    using namespace std;
     
    struct node{
        int a, b, len;
    };
     
    node edge[90000 + 5] = { };
    int father[90000 + 5] = { };
    int n = 0;
    int tot = 0;
     
    bool cmp(node a, node b)
    {
        return a.len < b.len;    
    }
     
    int getfather(int x)
    {
        if(x != father[x]){
            father[x] = getfather(father[x]);    
        }
        return father[x];
    }
     
    void  kruskal()
    {
        int x, y, k, cnt, tt;
        cnt = 0;
        k = 0;
        tt= 0;
        while(cnt < n - 1){
            k++;
            x = getfather(edge[k].a);
            y = getfather(edge[k].b);
            if(x != y){
                father[x] = y;
                tt += edge[k].len;
                cnt++;
            }
        }
        printf("%d", tt);    
    }
     
    int main()
    {
        scanf("%d", &n);
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= n; j++){
                int t = 0;
                scanf("%d", &t);
                if(i != j){
                    tot++;
                    edge[tot].a = i;
                    edge[tot].b = j;
                    edge[tot].len = t;
                }
            }
        }
        for(int i = 1; i <= n; i++){
            father[i] = i;
        }
        sort(edge + 1, edge + tot + 1, cmp);
        kruskal();
        
        return 0;
    }

    多谢大家观看!!!

    本蒟蒻可能有错,大家请指出!!QWQ

    (悄悄的说。。。。(不喜勿喷QWQ

  • 相关阅读:
    简单的模板解析函数
    HTML通过事件传递参数到js 二 event
    HTML通过事件传递参数到js一
    通过this获取当前点击选项相关数据
    LeetCode 20. 有效的括号(Valid Parentheses)
    LeetCode 459. 重复的子字符串(Repeated Substring Pattern)
    LeetCode 14. 最长公共前缀(Longest Common Prefix)
    LeetCode 168. Excel表列名称(Excel Sheet Column Title)
    LeetCode 171. Excel表列序号(Excel Sheet Column Number) 22
    LeetCode 665. 非递减数列(Non-decreasing Array)
  • 原文地址:https://www.cnblogs.com/ctime/p/11405237.html
Copyright © 2011-2022 走看看