zoukankan      html  css  js  c++  java
  • nyoj-38-布线问题

    
    
    //我的prim算法
    #include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> #define MAX 0x0fffffff using namespace std; int map[501][501],minnum[501]; int prim(int n) { int sum=0,i,j; for(i=1;i<=n;i++) { minnum[i]=map[1][i]; } minnum[1]=0; for(i=1;i<n;i++) { int min=MAX,k; for(j=2;j<=n;j++) { if(minnum[j]!=0&&minnum[j]<min) { min=minnum[j]; k=j; } } sum+=min; minnum[k]=0; for(j=2;j<=n;j++) { minnum[j]=minnum[k]+map[k][j]<minnum[j]?minnum[k]+map[k][j]:minnum[j]; } } return sum; } int main() { int n,v,e,a,b,c; scanf("%d",&n); while(n--) { memset(map,127,sizeof(map)); scanf("%d%d",&v,&e); while(e--) { scanf("%d%d%d",&a,&b,&c); map[a][b]=c; map[b][a]=c; } int min=MAX; for(int i=0;i<v;i++) { scanf("%d",&a); min=min>a?a:min; } printf("%d ",min+prim(v)); } return 0; }
    
    
    
    //prim算法解决  图论同学的代码
    
    #include <iostream>
    #include <cstdio>
    #include <string.h>
    using namespace std;
    #define MAX 0x0ffffff
    int map[510][510],lowcost[510];
    int N,sum;
    int min(int x,int y){return x<y?x:y;}
    void prim()
    {
        sum=0;
        for(int i=1;i<=N;i++)               //初始化
            lowcost[i]=map[1][i];
        lowcost[1]=0;                    //等于零表示在最小路径集合中
        for(int i=2;i<=N;i++)
        {
            int k,minn=MAX;
            for(int j=2;j<=N;j++)           //找最小边
            {
                if(lowcost[j]<minn&&lowcost[j]!=0)
                {
                    minn=lowcost[j];
                    k=j;
                }
            }
            sum+=minn;
            lowcost[k]=0;
            for(int j=2;j<=N;j++)
                if(map[k][j]<lowcost[j])
                    lowcost[j]=map[k][j];
        }
    }
    int main()
    {
        int T,m,minn;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&N,&m);
            for(int i=0;i<=N;i++)
                for(int j=0;j<=N;j++)
                    map[i][j]=MAX;
            while(m--)
            {
                int x,y,len;
                scanf("%d%d%d",&x,&y,&len);
                map[x][y]=map[y][x]=len;
            }
            minn=MAX;
            for(int i=1;i<=N;i++)
            {
                scanf("%d",&m);
                minn=min(minn,m);
            }
            prim();
            printf("%d
    ",sum+minn);
        }
        return 0;
    }
    //自己写的kruskal算法

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<math.h>
    using namespace std;
    struct build
    {
        int b,e,num;
    }bu[125000];
    bool cmp(build a,build b)
    {
        return a.num<b.num;
    }
    int p[510];
    int find(int n)
    {
        return p[n]==n?n:p[n]=find(p[n]);
    }
    int kruskal(int m)
    {
        int sum=0,i;
        for(i=0;i<510;i++)
            p[i]=i;
        sort(bu,bu+m,cmp);
        for(i=0;i<m;i++)
        {
            int x,y; x=find(bu[i].b);y=find(bu[i].e);
            if(x!=y)
            {
                sum+=bu[i].num;
                p[x]=y;
            }
        }
        return sum;
    }
    
    int main()
    {
        int n,v,e,i,a;
        scanf("%d",&n);
        while(n--)
        {
            scanf("%d%d",&v,&e);
            for(i=0;i<e;i++)
            scanf("%d%d%d",&bu[i].b,&bu[i].e,&bu[i].num);
            int min=7634634;
            for(i=0;i<v;i++)
            {
                scanf("%d",&a);
                if(a<min)
                min=a;
            }
            printf("%d
    ",min+kruskal(e));
        }
        return 0;
    }

    //用我自己的方法进行了优化

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<math.h>
    using namespace std;
    struct build
    {
    int b,e,num;
    }bu[125000];
    bool cmp(build a,build b)
    {return a.num<b.num;}
    int p[501];
    int find(int n)
    {return p[n]==n?n:p[n]=find(p[n]);}
    int kruskal(int n,int m)
    {
    int sum=0,i,flag=0;
    for(i=0;i<510;i++)
    p[i]=i;
    sort(bu,bu+m,cmp);
    for(i=0;i<m;i++)
    {
    int x,y; x=find(bu[i].b);y=find(bu[i].e);
    if(x!=y)
    {
    sum+=bu[i].num;
    flag++;
    p[x]=y;
    }
    if(flag==n-1)
    break;
    }
    return sum;
    }

    int main()
    {
    int n,v,e,i,a;
    scanf("%d",&n);
    while(n--)
    {
    scanf("%d%d",&v,&e);
    for(i=0;i<e;i++)
    scanf("%d%d%d",&bu[i].b,&bu[i].e,&bu[i].num);
    int min=7634634;
    for(i=0;i<v;i++)
    {
    scanf("%d",&a);
    if(a<min)
    min=a;
    }
    printf("%d ",min+kruskal(v,e));
    }
    return 0;
    }

     
  • 相关阅读:
    ch_6802 車的放置
    ch_POJ2182 Lost Cows
    ch_4201 楼兰图腾
    luogu_P3368【模板】树状数组 2
    门面
    建造者
    模板方法
    状态
    抽象工厂
    工厂方法
  • 原文地址:https://www.cnblogs.com/nylg-haozi/p/3213923.html
Copyright © 2011-2022 走看看