#include<iostream>
#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
#define MAX 505
#define inf 10000
int map[MAX][MAX];
int extra[MAX];
int N;//测试数据的个数
int v,e;//v是定点数,e是边数
void init()
{
int i,j;
for(i=0;i<MAX;i++)
{
for(j=0;j<MAX;j++)
{
map[i][j]=inf;
}
extra[i]=0;
}
}
int prim()
{
int sum=0;
//这个相当于堆栈,每一次访问过的元素都放在这个里面
int u[MAX];int ukey=1;
//初始化,把所有点初始化为0
int visited[MAX];
int i;int j;
for(i=0;i<MAX;i++)
{
visited[i]=0;
}
//把第一个元素压入堆栈
u[ukey]=1;//1代表第一个点
visited[u[ukey]]=1;//第一个点访问过
while(ukey<=v-1)
{
//找到最短的一个
int min=inf;
int minj=inf;
//从已经访问过的点钟选一个,找出跟没有访问过的点的最短的连线
for(i=1;i<=ukey;i++)
{
int ElementU=u[i];//取出一个元素(这个代表已经访问过的点)
//minj代表的是没有访问过的点
//从没有访问过的点中选择一个
for(j=1;j<=v;j++)
{
if(!visited[j])
{
//找出最小值
if(min>map[ElementU][j])
{
min=map[ElementU][j];
minj=j;
}
}
}
}
sum+=min;
//压入u当中
ukey++;
u[ukey]=minj;
visited[u[ukey]]=1;
}//while
return sum;
}
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d",&N);
while(N--)
{
//初始化
init();
//输入
scanf("%d %d",&v,&e);
int i;
for(i=0;i<e;i++)
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
map[a][b]=c;
map[b][a]=c;
}
for(i=1;i<=v;i++)
{
scanf("%d",&extra[i]);
}
//处理
int min=inf;
for(i=1;i<=v;i++)
{
if(min>extra[i])
{
min=extra[i];
}
}
printf("%d\n",min+prim());
}
return 0;
}
(精)(图论加强)布线问题(最小生成树)
最新推荐文章于 2020-12-04 20:53:11 发布