题意:给出一部分村庄之间的距离,求最小的公路总长度。
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1233
思路:prim算法求最小生成树,指定初始节点,以迭代的方式找出与最小生成树种各节点权重最小的边,加入到最小生成树中。
三个数组:1.cos 存最小生成树的边的权值
2.costs 初始化数组
3.vis 判定节点是否已加入数组中
三个for循环:1.重复查找
2.搜寻未被访问过且权值最小的点
3.查找从这个点到下一个权值最小的点
时间复杂度:O(n*n),适合稠密图,不断找最小边
代码:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
const int INF = 1e9;
int vis[110];
int costs[110][110];
int n;
int prime()
{
int cos[110];
fill(cos, cos+n, INF);
for(int i=0; i<n; i++)
{
if(cos[i] > costs[i][0])
cos[i] = costs[i][0];
}
memset(vis,0,sizeof vis);
int rt = 0;
vis[0]=1;
for(int j=0; j<n; j++)
{
int p=0,mim=INF;
for(int i=0; i<n; i++)
{
if( !vis[i] && cos[i] < mim)
{
mim = cos[i];
p=i;
}
}
if(mim != INF)
rt += mim;
vis[p]=1;
for(int i=0; i<n; i++)
{
if( !vis[i] && cos[i]>costs[p][i])
{
cos[i]=costs[p][i];
}
}
}
return rt;
}
int main()
{
while(cin >> n)
{
if(!n) break;
int v1,v2,cost;
for(int i=0; i< (n*(n-1))>>1; i++)
{
scanf("%d%d%d",&v1,&v2,&cost);
costs[v1-1][v2-1] = costs[v2-1][v1-1] = cost;
}
cout << prime()<< endl;
}
return 0;
}