数据结构实验之图论九:最小生成树(Prim算法)

数据结构实验之图论九:最小生成树
Time Limit: 1000 ms Memory Limit: 65536 KiB

Problem Description
有n个城市,其中有些城市之间可以修建公路,修建不同的公路费用是不同的。现在我们想知道,最少花多少钱修公路可以将所有的城市连在一起,使在任意一城市出发,可以到达其他任意的城市。

Input
输入包含多组数据,格式如下。

第一行包括两个整数n m,代表城市个数和可以修建的公路个数。(n <= 100, m <=10000)

剩下m行每行3个正整数a b c,代表城市a 和城市b之间可以修建一条公路,代价为c。

Output
每组输出占一行,仅输出最小花费。

Sample Input
3 2
1 2 1
1 3 1
1 0
Sample Output
2
0
Hint
Source
赵利强

错误代码1:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define inf 0x3f3f3f3f
int e[3001][3001],dis[1000001],book[1000001];
int prim(int n,int m)
{
    int countt=0,sum=0;
    memset(book,0,sizeof(book));
    memset(dis,0,sizeof(dis));
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            if(i==j)e[i][j]=0;
            else e[i][j]=inf;
        }
    }
    for(int i=1; i<=m; i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        if(e[x][y]>z)
        {
            e[x][y]=z;
            e[y][x]=z;
        }
    }
    for(int i=1; i<=n; i++)
    {
        dis[i]=e[1][i];
    }
    book[1]=1;
    countt++;
    int j;
    while(countt<n)
    {
        int maxx=inf;
        for(int i=1; i<=n; i++)
        {
            if(book[i]==0&&dis[i]<maxx)
            {
                maxx=dis[i];
//                printf("maxx=%d\n",maxx);
                j=i;
            }
        }
        if(maxx==inf)return -1;
        countt++;
//        printf("countt =%d\n",countt);
        book[j]=1;
        sum+=dis[j];
//        printf("sum=%d\n",sum);
        for(int i=1; i<=n; i++)
        {
            if(book[i]==0&&dis[i]>e[j][i])
            {
                dis[i]=e[j][i];
            }
        }
    }
    return sum;
}
int main()
{
   int n,m;
   while(~scanf("%d%d",&n,&m))
   {
       if(m!=n-1||m==0)printf("0\n");
       else printf("%d\n",prim(n,m));
   }
   return 0;
}


/***************************************************
User name: jk170427刘含
Result: Runtime Error
Take time: 0ms
Take Memory: 0KB
Submit time: 2018-08-05 16:29:55
****************************************************/

Runtime error的原因是
下面输出的时候不用判断是不是构成了最小生成树;直接输出就可以

错误代码2:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define inf 0x3f3f3f3f
int e[1001][1001],dis[1001],book[1001];
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        if(m==0)printf("0\n");
        memset(book,0,sizeof(book));
        memset(dis,0,sizeof(dis));
        int countt=0,sum=0;
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                if(i==j)e[i][j]=0;
                else e[i][j]=inf;
            }
        }
        for(int i=1; i<=m; i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            if(e[x][y]>z)
            {
                e[x][y]=z;
                e[y][x]=z;
            }
        }
        for(int i=1; i<=n; i++)
        {
            dis[i]=e[1][i];
        }
        book[1]=1;
        countt++;
        int j;
        while(countt<n)
        {
            int minn=inf;
            for(int i=1; i<=n; i++)
            {
                if(book[i]==0&&dis[i]<minn)
                {
                    minn=dis[i];
                    j=i;
                }
            }
            if(minn==inf)
            {
                printf("0\n");
                break;
            }
            countt++;
            book[j]=1;
            sum+=dis[j];
            dis[j]=0;
            for(int i=1; i<=n; i++)
            {
                if(book[i]==0&&dis[i]>e[j][i])
                {
                    dis[i]=e[j][i];
                }
            }
            printf("%d\n",sum);//这里的输出应该放在外面
        }
    }
    return 0;
}


/***************************************************
User name: jk170427刘含
Result: Wrong Answer
Take time: 12ms
Take Memory: 528KB
Submit time: 2018-08-06 09:35:37
****************************************************/

正确代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define inf 0x3f3f3f3f
int e[1001][1001],dis[1001],book[1001];
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        if(m==0)printf("0\n");//是让从m条边里面选择n-1条边;不用判断m是否等于n-1;
        else
        {
            memset(book,0,sizeof(book));
            memset(dis,0,sizeof(dis));
            int countt=0,sum=0;
            for(int i=1; i<=n; i++)
            {
                for(int j=1; j<=n; j++)
                {
                    if(i==j)e[i][j]=0;
                    else e[i][j]=inf;
                }
            }
            for(int i=1; i<=m; i++)
            {
                int x,y,z;
                scanf("%d%d%d",&x,&y,&z);
                if(e[x][y]>z)//注意判断重边
                {
                    e[x][y]=z;
                    e[y][x]=z;
                }
            }
            for(int i=1; i<=n; i++)
            {
                dis[i]=e[1][i];
            }
            book[1]=1;
            countt++;
            int j;
            while(countt<n)
            {
                int minn=inf;
                for(int i=1; i<=n; i++)
                {
                    if(book[i]==0&&dis[i]<minn)
                    {
                        minn=dis[i];
                        j=i;
                    }
                }
                if(minn==inf)
                {
                    break;
                }
                countt++;
                book[j]=1;
                sum+=dis[j];
                dis[j]=0;
                for(int i=1; i<=n; i++)
                {
                    if(book[i]==0&&dis[i]>e[j][i])
                    {
                        dis[i]=e[j][i];
                    }
                }
            }
            printf("%d\n",sum);
        }
    }
    return 0;
}


/***************************************************
User name: jk170427刘含
Result: Accepted
Take time: 16ms
Take Memory: 528KB
Submit time: 2018-08-06 10:21:01
****************************************************/

猜你喜欢

转载自blog.csdn.net/BHliuhan/article/details/81450734