• HDU 1102 Kruscal算法


    题目大意:
    给定村庄的数量,和一个矩阵表示每个村庄到对应村庄的距离,矩阵主对角线上均为1

    在给定一个数目Q,输入Q行之间已经有通道的a,b

    计算还要至少修建多少长度的轨道

    这道题目用Kruscal方法进行计算,先将已有路径记为0,再进行所有路径长度的排序(只计算一个下三角或一个上三角,还把主对角线去掉的那种),通过并查集相交的方法,来判断二者是否属于同一个连通分量,由小到大不断找到你选取的路径,将其加起来即可

    代码如下:

     1 #include <iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 #define N 105
     7 
     8 int mat[N][N];
     9 int visit[N],fa[N];
    10 struct Path{
    11     int x,y,d;
    12     bool operator<(const Path &m) const{
    13         return d<m.d;
    14     }
    15 }path[10010];
    16 
    17 int getHead(int x)
    18 {
    19     int a=x;
    20     while(fa[x]!=x) x=fa[x];
    21     fa[a]=x;
    22     return x;
    23 }
    24 
    25 bool Union(int x,int y)
    26 {
    27     int fa_x=getHead(x);
    28     int fa_y=getHead(y);
    29     if(fa_x==fa_y) return false;
    30     else{
    31         fa[fa_x]=fa_y;
    32         return true;
    33     }
    34 }
    35 void swap(int &a,int &b)
    36 {
    37     if(a<b){
    38         int temp=a;
    39         a=b;
    40         b=temp;
    41     }
    42 }
    43 
    44 int main()
    45 {
    46     int n,Q,a,b,k,ans;
    47     while(scanf("%d",&n)!=EOF){
    48         for(int i=1;i<N;i++) fa[i]=i;
    49         memset(visit,0,sizeof(visit));
    50         k=1,ans=0;
    51         for(int i=1;i<=n;i++)
    52             for(int j=1;j<=n;j++) cin>>mat[i][j];
    53         for(int i=1;i<=n;i++){
    54             for(int j=1;j<i;j++) path[k].x=i,path[k].y=j,path[k++].d=mat[i][j];
    55         }
    56 
    57         cin>>Q;
    58         for(int i=1;i<=Q;i++){
    59             cin>>a>>b;
    60             swap(a,b);
    61             path[(a-1)*(a-2)/2+b].d=0;
    62             /*if(!visit[a]) visit[a]=1,count++;
    63             if(!visit[b]) visit[b]=1,count++;*/
    64         }
    65 
    66         sort(path+1,path+k);
    67 
    68         /*for(int i=1;i<k;i++) cout<<path[i].d<<endl;
    69         cout<<"count"<<count<<endl;*/
    70         int count=0;
    71         for(int i=0;i<k;i++){
    72             if(Union(path[i].x,path[i].y)) ans+=path[i].d,count++;
    73             if(count==n-1) break;//当然这一步是为了做一个优化,让它可以提前跳出循环,
    74                                  //其实不跳出循环让它一直循环结束也是成立的,只是在找到n-1条边之后,
    75                                  //Union函数得到的判断均为false因为n个点都进入了同一个集合内
    76         }
    77         cout<<ans<<endl;
    78     }
    79     return 0;
    80 }
  • 相关阅读:
    1.MySql安装
    struts文件上传、文件下载
    Java内存模型
    虚拟机类加载机制
    JAVA内存管理
    算法
    POI
    SSH项目(1)
    classpath路径和properties
    AngularJS路由实现单页面跳转
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/3867488.html
Copyright © 2020-2023  润新知