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;
}

 
原文地址:https://www.cnblogs.com/nylg-haozi/p/3213923.html