题意:给出一个矩阵,代表着城镇直接的距离,之后给出一些已经连通的点,然后求,让所有点都连通的最小花费
思路:赤裸裸的最小生成树。。。prime水之。
#include<iostream>
#define max 105
#define inf 0xffffff
int vis[max],map[max][max],lowcost[max],n;
//lowcost[i]记录的已经标记的节点(S1)到其它节点i(S2)的权值最小的值
int prime(int v)
{
int i,j,minn,k,sum=0;
for(i=1;i<=n;i++) lowcost[i]=map[v][i];//以v节点初始化
vis[v]=1;//把v标记 记录到集合S1中
for(i=2;i<=n;i++)//寻找n-1次
{
minn=inf;
for(j=1;j<=n;j++)
if(lowcost[j]<minn&&!vis[j])//找到集合S2中最小的权值累加并把节点k并入到
{ //集合S1中
minn=lowcost[j],k=j;
}
sum+=minn,vis[k]=1;
for(j=1;j<=n;j++)//因为S1集合加入了节点k,所以要更新lowcost
//lowcost更新为已经找到的节点到集合S2中的距离(map[k][j]),和原来S1集合
//(未加入K)时候到集合S2中的距离的较小值,这个值才是当前S1集合到S2集合
//中距离最小的点。
if(lowcost[j]>map[k][j]&&!vis[j])
lowcost[j]=map[k][j];
}
return sum;
}
int main()
{
int i,j,a,b,m;
while(scanf("%d",&n)!=EOF)
{
memset(vis,0,sizeof(vis));
memset(map,inf,sizeof(map));
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&map[i][j]);
scanf("%d",&m);
for(i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
map[a][b]=map[b][a]=0;//已经建立的道路就把权值赋值为0,生成树的
} //值不影响最终结果
printf("%d\n",prime(1));
}
}