题目链接: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 ",mincost); } return 0; }