题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=38
任意选择一个起点求最小生成树,然后最后在加上某个花费最少的点,算法选择普里姆算法.
#include <cstdio>
#include <cstring>
#define inf 0x3f3f3f3f
int mp[505][505];
int v,e;
int ans;
int d[505];
int f[505];
void prim()
{
memset(f,0,sizeof f);
for(int i = 1;i <= v;++i)
d[i] = mp[1][i];
int cnt = 1;
f[1] = 1;
while(cnt < v)
{
int Min = inf;
int k;
for(int i = 1;i <= v;++i)
{
if(d[i] < Min && !f[i])
{
Min = d[i];
k = i;
}
}
ans += d[k];
cnt++;
f[k] = 1;
for(int i = 1;i <= v;++i)
{
if(!f[i] && d[i] > mp[k][i])
d[i] = mp[k][i];
}
}
}
int main()
{
int _;
scanf("%d",&_);
while(_--)
{
scanf("%d%d",&v,&e);
for(int i = 1;i <= v;++i)
for(int j = 1;j <= v;++j)
mp[i][j] = inf;
for(int i = 1;i <= v;++i)
mp[i][i] = 0;
for(int i = 1;i <= e;++i)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
mp[a][b] = mp[b][a] = c;
}
int temp,Min = inf;
for(int i = 1;i <= v;++i)
{
scanf("%d",&temp);
if(temp < Min)
Min = temp;
}
ans = 0;
prim();
printf("%d\n",ans + Min);
}
return 0;
}