F - Jungle Roads

题目链接:http://poj.org/problem?id=1251

题意:就是给你n个点,告诉你他们的连通情况,让你找一条最短路径使维修道路花费的钱最少,最小生成树问题,可以用prim解法和 kruskal解法,暂时还只会prim解法。

思路:以某一顶点出发,找权值最小的、相邻的边,找到后,并入该顶点 ,直到顶点的数为n 为止

心得:做题一定要细心,做这题时出了好多小错误,改了好久,心好累。一个较大的错误是自己把对标记清零的函数写到循环外了,结果造成第二组数据是第一组数据累加之后的结果。还有就是遇到字符输入时,一定要考虑空格的情况。

#include <iostream>
#include<cstdio>
#include<cstring>
#define MAX 100000
using namespace std;
int g[30][30];//邻接矩阵
int lowcost[30];//最短边
int mincost;//费用
int vis[30];//标记
int n;
void prim()
{
    mincost=0;
    for(int i=1; i<=n; i++)
        lowcost[i]=g[1][i];
    vis[1]=1;
    int k;
    for(int i=1; i<n; i++)//多写了一个等号结果就出错了,变成了100216,100030
    {
        int min=MAX;
        k=0;
        for(int j=1; j<=n; j++)
        {
            if(!vis[j]&&lowcost[j]<min)
               {
                   min=lowcost[j];
                k=j;//把k=j写到循环外去了

               }
        }
        mincost+=min;
        vis[k]=1;
        for(int j=1; j<=n; j++)
        {
            if(!vis[j]&&g[k][j]<lowcost[j])
                lowcost[j]=g[k][j];
        }
    }
}
int main()
{
    int c,cc;
    char cha[2],ch[2];
    while(scanf("%d",&n),n)
    {
        memset(vis,0,sizeof(vis));//对标记函数函数清零,放在了循环外面,导致第二组数据的结果与第一组数据累加了
         for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
            {
                if(i==j)
                    g[i][i]=0;
                else g[i][j]=MAX;
            }
        getchar();
        for(int j=1; j<n; j++)
        {
            scanf("%s %d",ch,&c);
            for(int i=0; i<c; i++)
            {
                scanf(" %s %d",cha,&cc);
                g[ch[0]-'A'+1][cha[0]-'A'+1]=cc;
                g[cha[0]-'A'+1][ch[0]-'A'+1]=cc;
            }
        getchar();
        }
        prim();
        printf("%d\n",mincost);
    }
    return 0;
}

 

posted @ 2016-07-25 19:07  踮起脚望天  阅读(186)  评论(0编辑  收藏  举报