zoukankan      html  css  js  c++  java
  • 最小生成树模板题POJ

    POJ - 1287超级模板题

    大概意思就是点的编号从1到N,会给你m条边,可能两个点之间有多条边这种情况,求最小生成树总长度?

    这题就不解释了,总结就算,prim是类似dijkstra,从第一个点出发,每次走这个点没走过的最小边权值,这样不断找下去就可以找出,本质就是贪心算法

    而kruskal是利用并查集,先按照边权值大小排序,然后从小的边开始往里面添加边,利用并查集判断是否在一个联通分量里面(就是是否相连)如果不相

    连就建立边,从而建图,注意,节点编号如果是从1->n,那么相应初始化就应该从1->N;

    prim版本:

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<string.h>
     4 using namespace std;
     5 const int INF = 0x3f3f3f3f;
     6 const int maxx = 1e2+7;
     7 int cost[maxx][maxx];
     8 int mincost[maxx];
     9 bool used[maxx];
    10 int v;
    11 int m,n;
    12 int prim(){
    13   for (int i=1;i<=n;i++){
    14     mincost[i]=INF;
    15     used[i]=false;
    16   }
    17  mincost[1]=0;//这里的数组的编号,代表我最开始建图的点
    18   int res=0;
    19   while(true){
    20     int v = -1;
    21     for (int u=1;u<=n;u++){ //枚举边找到这个点的下一个边权值最小的点
    22         if (!used[u] && (v==-1 || mincost[u] < mincost[v])) v=u; 
    23     }
    24     if (v == -1)break;//没有的话就返回,无法建图
    25     used[v]=true;//顶点加入
    26     res+=mincost[v];
    27     for (int u=1;u<=n;u++){
    28         mincost[u] = min(mincost[u],cost[v][u]);//???
    29     }
    30   }
    31   return res;
    32 }
    33 int main(){
    34   int tmp1,tmp2,tmp3;
    35    while(scanf("%d",&n) && n){
    36       scanf("%d",&m);
    37       if (m==0){
    38         cout<<"0"<<endl;
    39         continue;
    40       }
    41      for (int i=1;i<=n;i++){
    42         for(int j=1;j<=n;j++){
    43             if (i==j)cost[i][j]=0;
    44             else cost[i][j]=INF;
    45         }
    46      }
    47      for (int i=1;i<=m;i++){
    48         scanf("%d%d%d",&tmp1,&tmp2,&tmp3);
    49         if (tmp3<cost[tmp1][tmp2])cost[tmp1][tmp2]=cost[tmp2][tmp1]=tmp3;//更新成最短边
    50      }
    51     cout<<prim()<<endl;
    52    }
    53   return 0;
    54 }

    Kruskal

    #include<iostream>
    #include<string.h>
    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    struct node{
      int u,v,w;
    }a[10050];
    int p[10055];
    int r[10055];
    int n,m;
    int find(int x){return p[x] == x ? x : p[x] = find(p[x]);}//找根节点
    int cmp(node x,node y)
    {
        return x.w<y.w;//按照边权值排序
    }
    int Kruskal(){
            int ans=0;
            int num=0;
            for (int i=1; i<=n; i++)p[i]=i;
            sort(a+1,a+1+m,cmp);
            for (int i=1; i<=m; i++)
            {
                int x=find(a[i].u);//出发点的根节点
                int y=find(a[i].v);//到达点的根节点
                if (x!=y)//不是一个根节点
                {
                    ans+=a[i].w;//连接
                    p[x]=y;//y是x的父亲节点
                    num++;//建立好了n-1条边
                }
                if (num==n-1){
                    break;
                }
            }
        return ans;
    }
    int main()
    {
        int tmp1,tmp2,tmp3;
        while(~scanf("%d",&n))
        {
            if (n==0)break;
            scanf("%d",&m);
            for (int i=1; i<=m; i++)
            {
                scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
            }
            printf("%d
    ",Kruskal());
        }
        return 0;
    }
    有不懂欢迎咨询 QQ:1326487164(添加时记得备注)
  • 相关阅读:
    选择排序——Java实现
    冒泡排序——Python实现
    基数排序——Java实现
    Sqoop迁移Hadoop与RDBMS间的数据
    Hive Join
    Hadoop 完全分布式部署(三节点)
    springboot自定义异常处理
    linux下安装redis
    windows 下tomcat重启脚本
    解决rabbin首次请求慢的问题
  • 原文地址:https://www.cnblogs.com/bluefly-hrbust/p/9410730.html
Copyright © 2011-2022 走看看