QS Network(最小生成树)

QS Network

题意:

     一种叫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算法,以后会补上;


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值