zoukankan      html  css  js  c++  java
  • 最小生成树

    1.kruskal(克鲁斯卡尔)算法

    将所有边由小到大排序,依次进行有效的扩展(即有一节点加入集合),直到已经形成一棵树,此时生成的树即为最小生成树
    ps:需用并查集才更好

    ```

    //洛谷1546
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n,cnt,sum,ans;
    int fa[105];
    
    struct edg{
        int from,to,dis;
    }edge[10005];
    
    bool cmp(edg x,edg y){
        return x.dis<y.dis;
    }
    
    int find(int x)                                                                                                         //查找根节点
    { 
        if(fa[x]==x) return x;
        return fa[x]=find(fa[x]);
    }
    
    void join(int a,int b){
        int x=find(a);
        int y=find(b);
        if(x!=y) fa[x]=y;
    }
    
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++){
                int x;
                scanf("%d",&x);
                if(i!=j){
                    cnt++;
                    edge[cnt].dis=x;
                    edge[cnt].from=i,edge[cnt].to=j;
                }
            }
        for(int i=1;i<=n;i++) fa[i]=i;
        sort(edge+1,edge+cnt+1,cmp);
        for(int i=1;i<=cnt;i++){
            if(find(edge[i].from)!=find(edge[i].to)){
                join(edge[i].from,edge[i].to);
                sum+=edge[i].dis;
                ans++;
            }
            if(ans==n-1) break;
        }
        printf("%d",sum);
        return 0;
    }
    ```

    2.prim(普里姆)算法

    每次选一个 与最小生成树相连的最小花费最少的节点 进入最小生成树,并用这个节点尝试更新它所连所有节点的 与最小生成树相连的最小花费(因为有节点进入,最小生成树发生改变),直到最终完成

    ```

    //洛谷1265
    #include<cstdio>
    #include<cmath>
    using namespace std;
    int n,cnt;
    double sum;
    int mst[5005];
    double dis[5005][5005],mincost[5005];
    
    struct point{
        int x,y;
    }city[5005];
    
    double qdis(int a,int b){
    //  if(dis[a][b]) return dis[a][b];
    //  else 
    //  return dis[a][b]=dis[b][a]=sqrt(abs(city[a].x-city[b].x)*abs(city[a].x-city[b].x)+abs(city[a].y-city[b].y)*abs(city[a].y-city[b].y));
        return sqrt(abs(city[a].x-city[b].x)*abs(city[a].x-city[b].x)+abs(city[a].y-city[b].y)*abs(city[a].y-city[b].y));
    }
    
    void prim(int t){//函数没写好 懒得改了 明白怎么回事就好
        if(cnt==n-1) return ;
        cnt++;
        int k; double minn=0x3f3f3f3f;
        for(register int i=1;i<=n;i++) {
            if(!mst[i]&&mincost[i]<minn){
                minn=mincost[i];
                k=i;
            }
        }
        mst[k]=1;
        for(register int i=1;i<=n;i++)
            if(!mst[i]&&qdis(i,k)<mincost[i])
                mincost[i]=qdis(i,k);
        sum+=minn;
        prim(k);
        return ;
    }
    
    int main(){
        scanf("%d",&n);
        for(register int i=1;i<=n;i++)
            scanf("%d %d",&city[i].x,&city[i].y);
        for(register int i=2;i<=n;i++) mincost[i]=qdis(i,1);
        mst[1]=1;
        prim(1);
        printf("%.2f",sum);
        return 0;
    }
    ```
    版权声明:本文为博主原创文章,未经博主允许不得转载。 博主:https://www.cnblogs.com/Menteur-Hxy/
  • 相关阅读:
    uboot编译配置过程
    APUE-数据库函数库
    值得推荐的C/C++框架和库 (真的很强大)
    ubuntu12.04图形界面与命令行界面切换
    ubuntu14.04 升级gcc的方法
    4. H5+css3
    3,css 内容
    2. 浏览器兼容性问题
    1,http协议
    页面添加水印
  • 原文地址:https://www.cnblogs.com/Menteur-Hxy/p/9248053.html
Copyright © 2011-2022 走看看