• P1546 [USACO3.1]最短网络 Agri-Net(洛谷)


    题目传送口

      很明显,这个题用邻接矩阵+dfs就能出(从不同点出发搜,且搜的时候更新最小值,可以剪枝,并且不成环) 。但算法标签中有并查集,因此此题尝试用并查集的方法来解决类似的连通图问题。

      核心算法:

        把每一条边按权值从小到大排序,然后依次看,如果两个端点不在一个集合里,就把他们合并,累加路径长度。如果已经包含所有点了,直接输出数据退出。(其实这也恰好是Kruskal算法的思想),在这里通过并查集来实现。

    实现代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    int par[100];
    int rank[100];
    int n;
    int len[101][101];
    int ans=0;        //储存总路长 
    int remain=0;
    void init(){
        for(int i=1;i<=n;i++){
            par[i]=i;
            rank[i]=0;            //高度最初为0 
        }
    }
    
    int find(int x){
        if(par[x]==x){
            return x;
        }else return par[x]=find(par[x]);
    }
    
    void unite(int x,int y){
        x=find(x);
        y=find(y);
        if(x==y)    return;
        
        if(rank[x]<rank[y]){
            par[x]=y;
        }else{
            par[y]=x;
            if(rank[x]==rank[y]){
                rank[x]++;            //高度加1 
            }
        }
    }
    
    bool same(int x,int y){
        return find(x)==find(y);
    }
    
    
    typedef struct node{
        int length;        //保存长度
        int a;
        int b;            //保存两个端点 
    }T;
    T s[10000];
    
    bool cmp(T k1,T k2){        //增序 
        return k1.length<k2.length;
    }
    
    int main(){
        cin>>n;
        remain=n-1;
        init();
        
        int t=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                cin>>len[i][j];
                if(i>j){
                    s[t].length=len[i][j];        //储存长度 
                    s[t].a=i;                    //储存端点 
                    s[t++].b=j;
                }
            }
        }
        
        sort(s,s+t,cmp);         //边进行排序 
        
        for(int i=0;i<t;i++){
            if(remain==0)    break;        //网络建完
            if(same(s[i].a,s[i].b)) continue;
            if(!same(s[i].a,s[i].b)){
                ans+=s[i].length;
                unite(s[i].a,s[i].b);        //进行合并
                remain--; 
            }
        }
        
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    288.软件开发过程与软件测试
    287.软件测试概述
    离散数学课程重点
    博客园美化
    渗透测试-Getshell总结
    C++迭代器
    每日一题2
    计算机网络面试总结(传输层)
    每日一题-1
    网络安全必备技能
  • 原文地址:https://www.cnblogs.com/xwh-blogs/p/12607825.html
Copyright © 2020-2023  润新知