Problem Address:http://poj.org/problem?id=1251
一看就是用Prim算法求最小生成树。
之前已经学过Prim算法,而且这两天刚刚看到,可是还没敲过代码。
所以借此机会学习一下。
重新看了一次,上网找资料什么的,可是虽然是懂了,但就是不知道要怎么写。
n久后决定还是自己试一下才行。
所以敲敲敲……
没想到就这么敲出来了,而且结果还不赖。Debug了一个数据后就过Sample了,一提交,RTE。看了discuss,把scanf和getchar改为了cin,再提交,AC。
很好很强大。
其实Prim算法还是很好理解的,看是实现起来思路可能就有点卡。特别是看着里面说判断是否在某个集合中,所以有点摸不着头脑。
以下贴代码:
#include <iostream>
using namespace std;
const int MAX = 100000;
int V[30], vn;//V用来存放已经访问过的点,vn用于计算V中的个数
int n, map[30][30], sum;//map用于存放权值,sum用于计算总路线
bool visited[30];//记录是否已访问过
void prime()
{
int i,j,min,xn;
while(vn<n)//如果vn还未到达n则继续寻找下一条边
{
min = MAX;
for (i=1; i<=vn; i++)//对于V中的每个点搜索
{
for (j=1; j<=n; j++)//对于V中每个点的每条邻边进行搜索以找出最小的边
{
if (!visited[j])
{
if (map[V[i]][j]<min)
{
min = map[V[i]][j];//记录下最小的边
xn = j;//记录最小边所对应的(不在V中的)点
}
}
}
}
visited[xn] = true;//把该点设为已访问
sum += min;//路线值增加
vn++;//V的个数增加
V[vn] = xn;//把该点存入V中
}
}
int main()
{
int i,j,x,y,t;
char c;
while(cin>>n)
{
if (n==0) break;
for (i=1; i<=n; i++)
for (j=1; j<=n; j++)
map[i][j] = MAX;
for (i=1; i<=n; i++)
visited[i] = false;
for (i=1; i<n; i++)
{
cin>>c>>x;
y = c - 'A' + 1;
for (j=0; j<x; j++)
{
cin>>c>>t;
map[y][c-'A'+1]=t;
map[c-'A'+1][y]=t;
}
}
V[1] = 1;
visited[1] = true;
vn = 1;
sum = 0;
prime();
cout<<sum<<endl;
}
return 0;
}
p.s.学习算法是辛苦的,同时也是快乐的。这两天掌握了比较多的算法,要好好消化才行~