【持续更新】最小生成树题目集合

时间:2019-01-18
本文章向大家介绍【持续更新】最小生成树题目集合,主要包括【持续更新】最小生成树题目集合使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

(prim算法实现)

1)hdoj1233:还是畅通工程

赤裸裸的最小生成树

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1233

#include <iostream>
#include <vector>
#include <string.h>
#include <cmath>
#include <algorithm>
#define maxn 101
using namespace std;
int edges[maxn][maxn];
int main()
{
    int n,a,b,i,j,m,s,k;
    while(scanf("%d",&n) && n!=0)
    {
        bool visit[maxn]={false};
        int lowcost[maxn];
        int ans=0;
        fill(edges[0],edges[0]+n*n,INT_MAX);
        m=n*(n-1)/2;
        for(i=0;i<m;i++)
        {
            scanf("%d %d %d",&a,&b,&s);
            edges[a][b]=edges[b][a]=s;
        }
        visit[1]=true;
        for(i=1;i<=n;i++)
            lowcost[i]=edges[1][i];
        for(i=1;i<n;i++)
        {
            int min=INT_MAX;
            k=-1;
            for(j=1;j<=n;j++)
            {
                if(visit[j]==false && lowcost[j]<min)
                {
                    min=lowcost[j];
                    k=j;
                }//最短边
            }
            visit[k]=true;
              ans+=lowcost[k];
            for(j=1;j<=n;j++)
            {
                if(visit[j]==false && edges[k][j]<lowcost[j])
                    lowcost[j]=edges[k][j];
            }
        }
       printf("%d\n",ans);
    }
    return 0;
}

2)hdoj1875:畅通工程再续

简单最小生成树

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1875

#include <iostream>
#include <vector>
#include <string.h>
#include <cmath>
#include <algorithm>
#define maxn 105
using namespace std;
double dis[maxn][maxn];
struct Pos{
    int x,y;
}pos[maxn];
int main()
{
    int t,c,i,j;
    scanf("%d",&t);
    while(t--)
    {
        int num=0;
        double ans=0;
        int visit[maxn]={0};
        double lowcost[maxn];
        scanf("%d",&c);
        for(i=1;i<=c;i++)
            scanf("%d %d", &pos[i].x, &pos[i].y);
        for(i=1;i<=c;i++)
        {
            for (j = 1; j <= c; j++)
            {
                if(i==j) continue;
                double dist = sqrt(
                        (pos[i].x - pos[j].x) * (pos[i].x - pos[j].x) + (pos[i].y - pos[j].y) * (pos[i].y - pos[j].y));
                if (dist <= 1000 && dist >= 10)
                    dis[i][j] = dis[j][i] = dist;
                else
                    dis[i][j] = dis[j][i] = INT_MAX;
            }
        }
        visit[1]=1;
        num++;
        for(i=2;i<=c;i++)
            lowcost[i]=dis[1][i];
        for(i=1;i<c;i++)
        {
            double min=INT_MAX-1.0;//lowcost的值或者<=1000h或者为INT_MAX
            int k=-1;
            for(j=1;j<=c;j++)
            {
                if(visit[j]==0&&lowcost[j]<min)//且当前顶点中到j有符合条件的边
                {
                    min=lowcost[j];
                    k=j;
                }
            }
            if(k==-1) continue;
            visit[k]=1;
            num++;
            ans+=lowcost[k];
            for(j=1;j<=c;j++)
            {
                if(visit[j]==0&&dis[k][j]<lowcost[j])
                    lowcost[j]=dis[k][j];
            }
        }
        if(num!=c)
            printf("oh!\n");
        else
            printf("%.1f\n",ans*100);
    }
    return 0;
}

3)hdoj1879:继续畅通工程

巧妙设置小细节

http://acm.hdu.edu.cn/showproblem.php?pid=1879

#include <iostream>
#include <vector>
#include <string.h>
#include <cmath>
#include <algorithm>
#define maxn 105
using namespace std;
int state[maxn][maxn];
int edges[maxn][maxn];
int main()
{
    int n;
    while(scanf("%d",&n)&&n!=0)
    {
        int i,a,b,s,c,j,k;
        int ans=0;
        int visit[maxn]={0};
        int lowcost[maxn],closest[maxn];//closest[I]记录连接I结点的另一端上的结点
        fill(edges[0],edges[0]+n*n,INT_MAX);
        int m=n*(n-1)/2;
        for(i=1;i<=m;i++)
        {
            scanf("%d %d %d %d",&a,&b,&c,&s);
            if(s==1)
               edges[a][b]=edges[b][a]=0;//如果已经建立,那么就有限选这条边,置为0
            else
                edges[a][b]=edges[b][a]=c;
            state[a][b]=state[b][a]=s;
        }
        visit[1]=1;
        for(i=2;i<=n;i++)
        {
            lowcost[i] = edges[1][i];
            closest[i]=1;
        }
        for(i=1;i<n;i++)
        {
            int min=INT_MAX-1;
            for(j=1;j<=n;j++)
            {
                if(visit[j]==0&&lowcost[j]<min)
                {
                    min=lowcost[j];
                    k=j;
                }
            }
            visit[k]=1;
            ans+=edges[closest[k]][k];
            for(j=1;j<=n;j++)
            {
                if(visit[j]==0&&edges[k][j]<lowcost[j])
                {
                    lowcost[j]=edges[k][j];
                    closest[j]=k;
                }
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}