思路:
主要是普里姆算法,搜寻找到顶点的最小权值,然后加到里面。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int mini[51] ;
int a[51][51];
int vis[51];
int main()
{
int P, R;
while (cin >>P)
{
if(P == 0) break;
cin >> R;
getchar();
memset(mini , 44 , sizeof(mini));
memset(a , 44 , sizeof(a));
memset(vis , 0 , sizeof (vis));
for (int i=1 ; i <= R ; i++)
{
int b,c,d;
cin >> b >> c >> d;
a[b][c] = min(a[b][c] , d); //选取
a[c][b] = min(a[c][b] , d);
}
vis[1] = 1;
int ans = 0;
for (int i = 1 ; i <= P ; i++)
mini[i] = a[1][i];
for (int i = 2 ; i <= P ; i++)
{
int maxn = 105,e;
for (int j = 1 ; j <= P ; j++)
{
if (!vis[j] && mini[j] < maxn)
{
maxn = mini[j];
e = j;
}
}
ans += mini[e];
vis[e] = 1;
for (int j = 1 ; j <= P ; j++)
if (!vis[j] && a[e][j] < mini[j])
mini[j] = a[e][j];
}
cout << ans << endl;
}
return 0;
}
还有另外一种,运行时答案正确,但是提示错误是数组越界。。。求解释
错误:
代码:
#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
using namespace std;
const int Max = 105;
int a[55][55]; //表示边的权值
int vis[55]; //顶点是否被访问过了
int mini[55]; //每个顶点的最小权值
int p,r;
void Init() //赋初值
{
for(int i=1; i<=r+1; i++)
{
mini[i] = Max;
for(int j=1; j<=r+1; j++)
{
a[i][j] = Max;
}
}
}
int main()
{
while(cin >> p)
{
if (!p) break;
cin >> r;
getchar();
int i, j, cost;
memset(vis, 0,sizeof(vis));
Init();
for(int k=1; k<=r; k++)
{
cin >> i >> j >> cost;
if (a[i][j] > cost)
{
a[i][j] = cost;
}
mini[i] = a[i][j]; //顶点的最小权值
}
int sum = 0;
mini[1] = 0;
while(1) //普里姆算法
{
int flag = 0;
for(int l=1; l<=p; l++)
{
if(!vis[l] && (flag == 0 || mini[flag] > mini[l]))
{
flag = l;
}
}
if(flag == 0)
break;
vis[flag] = 1;
sum += mini[flag];
for(int k=1; k<=p; k++)
{
mini[k] = min(mini[k], a[flag][k]);
}
}
cout << sum << endl;
}
return 0;
}