38-布线问题
思路
最小生成树问题,普里姆算法
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXVEX = 505;
const int M = 0x3f3f3f3f;
int ans = 0; //记录最小费用
int u, v; //顶点数,边数
int W[1000]; //每个点与外部设备相连所需费用
typedef struct Map
{
int arc[MAXVEX][MAXVEX]; //邻接矩阵
int numVertexes; //顶点数
} MGraph;
int lowcost[MAXVEX]; //保存相关顶点间边的权值
void MiniSpanTree_Prim(MGraph *G)
{
int minx;
for (int i = 1; i <= G->numVertexes; i++)
{
lowcost[i] = G->arc[1][i]; //将与之有边的权值存入数组,记录1和i之间的权值
}
lowcost[1] = 0;
for (int i = 1; i <G->numVertexes; i++)
{
minx = M; //初始化最小权值为无穷
int j = 1, k;
while (j <= G->numVertexes)
{
if (lowcost[j] != 0 && lowcost[j] < minx)
{
minx = lowcost[j];
k = j; //将当前最小值的下表存入k
}
j++;
}
//cout<<adjvex[k]<<" "<<k<<endl;
ans += minx;
//cout<<ans<<endl;
lowcost[k] = 0; //将当前定点的权值设置为0,表示此顶点已经完成任务
for (j = 1; j <= G->numVertexes; j++)
{
if (lowcost[j] != 0 && G->arc[k][j] < lowcost[j])
{
lowcost[j] = G->arc[k][j]; //将较小权值存入lowcost
}
}
}
}
int main()
{
int t;
cin >> t;
while (t--)
{
MGraph G;
//memset(G.arc,M,sizeof(G.arc));
memset(lowcost, 0, sizeof(lowcost));
cin >> u >> v;
int x, y, s; //x,y相连的点,s是x,y之间点路费
G.numVertexes = u;
for (int i = 0; i <= u; i++)
{
for (int j = 0; j <= u; j++)
G.arc[i][j] = M;
}
for (int i = 0; i <= u; i++)
G.arc[i][i] = 0;
for (int i = 1; i <= v; i++)
{
cin >> x >> y >> s;
G.arc[x][y] = G.arc[y][x] = s;
// cout<<G.arc[x][y]<<" "<<G.arc[y][x]<<endl;
}
for (int i = 0; i < u; i++)
{
cin >> W[i];
}
sort(W, W + u);
ans = 0;
MiniSpanTree_Prim(&G);
ans += W[0];
cout << ans << endl;
}
return 0;
}