题意:
一种叫QS的生物,可以相互沟通,聊天;可以两QS直接聊天,也可以让人转达;
每两个生物之间都有一天网线,价值不一,每个QS都有一个类似router(路由器)(每个QS的router都不同)的东东,聊天的时候必须用到,而且每和一个QS聊天就需要一个router;现在需要每个QS都可以聊天而且花费最少,求最少费用,费用包括网线和router的钱;
示例:
10 20 30 //分别表示编号为1,2,3的QS,所用router的价钱;
0 100 200 //表示1-2网线100,1-3网线200;
100 0 300 //2-1网线100,2-3网线300;
200 300 0 //3-1网线200,3-2网线300;
网线是无向的;
思路:最小生成树就好了,边的权是网线加两端点的router;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INF 0x3f3f3f3f; //INF表示无穷大;
int router[1005]; //router数组用来存放QS的router的价钱;
int dis[1005][1005]; //每两个QS之间的网线;
int T, n; //T表示侧视样例,n表示QS的个数;
int book[1005]; //标记QS是否已连接;
int dis_a[1005]; //1到其他QS的权;
int Prime(){ //Prime算法;
int i, j;
book[1]=1; //1已连接;
for(i=1; i<=n; i++) //把1到其他QS的权存入数组;
dis_a[i]=dis[1][i];
int cnt=1; //记录已连接的点的个数;
int min_x; //最小权;
int sum=0; //总花费;
while(cnt<n){ //当cnt=n是,所有QS已连接,循环结束;
min_x=INF;
for(i=1; i<=n; i++)//找出距离1最小的边及对应点;
if(!book[i] && dis_a[i]<min_x){
min_x=dis_a[i];
j=i;
}
book[j]=1; //标记j点,表示已连接;
cnt++;
sum+=dis_a[j];
int k;
for(k=1; k<=n; k++) //更新每个QS到1的最小权
if(!book[k] && dis_a[k]>dis[j][k])
dis_a[k]=dis[j][k];
}
return sum;
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
int i, j;
for(i=1; i<=n; i++){
scanf("%d",&router[i]);
book[i]=0;
}
for(i=1; i<=n; i++)
for(j=1; j<=n; j++){
scanf("%d",&dis[i][j]);
if(i!=j) dis[i][j]+=router[i]+router[j]; //每条边的权包括网线加上QS的router;
}
int sum;
sum=Prime();;
printf("%d\n",sum);
}
}
这里我用的是Prime算法,当然也可以用Kruskal算法,以后会补上;