COGS 通信线路

通信线路

★★   输入文件: mcst.in   输出文件: mcst.out    简单对比
时间限制:1.5 s   内存限制:128 MB
问题描述
假设要在n个城市之间建立通信联络网,则连通n个城市只需要n-1条线路。这时, 如何在最行咨经费的前提下建立这个通信网。在每两个城市之间都可以设置—条线路,相应地都要付出一定的经济代价。n个城市之间,最多可能设置n(n- 1)/2条线路,那么,如何在这些可能的线路中选择n-1条,以使总的耗费最少呢?
【输入格式】
输入文件有若干行
第一行,一个整数n,表示共有n个城市
第2--n+1行,每行n个数,分别表示该城市与其它城市之间路线的费用,如果城市间不能建立通信则用-1表示
【输出格式】
一行,1个整数,表示最少总费用
【输入输出样例】
输入文件

-1 5 -1 -1 -1 -1 
5 -1 50 -1 -1 10
-1 50 -1 20 10 -1
-1 -1 20 -1 60 30
-1 -1 10 60 -1 100
-1 10 -1 30 100 -1
输出文件
75
【数据规模】
对于40%的数据,保证有n<100: 
对于60%的数据,保证有n<256; 

对于全部的数据,保证有n<=1501。


Kruskal

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
using namespace std;
struct node
{
    int x, y, dis;
}p[3000000];
int Find[15550];
int cmp(const void *a,const void *b)
{
    struct node *c=(struct node *)a;
    struct node *d=(struct node *)b;
    return c->dis-d->dis;
}
int f(int x)
{
    return x==Find[x]?x:Find[x]=f(Find[x]);
}


int main()
{
    freopen("mcst.in","r",stdin);
    freopen("mcst.out","w",stdout);
    int n, a, k=0;
    scanf("%d", &n);
    for(int i=1;i<=n;i++)
    {
        Find[i]=i;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            scanf("%d", &a);
            if(j<=i||a==-1)
            {
                continue;
            }
            p[k].x=i,p[k].y=j;
            p[k++].dis=a;
        }
    }
    qsort(p,k,sizeof(p[0]),cmp);
    int ans=0;
    for(int i=0;i<k;i++)
    {
        int x=f(p[i].x),y=f(p[i].y);
        if(x!=y)
        {
            ans+=p[i].dis;
            Find[y]=x;
        }
    }
    printf("%d\n",ans);
    return 0;
}

prim

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4.  
  5. #define maxn 1502
  6. #define Max 0x7f7f7f7f
  7.  
  8. using namespace std;
  9.  
  10. int Gra[maxn][maxn];
  11. int Min[maxn];
  12. bool Exi[maxn];
  13.  
  14. int n ;
  15.  
  16. int main()
  17. {
  18. freopen("mcst.in" ,"r",stdin );
  19. freopen("mcst.out","w",stdout);
  20. scanf("%d",&n);
  21. for (int i = 1 ; i <= n ; i ++ )
  22. {
  23. for (int j = 1 ; j <= n ; j ++ )
  24. {
  25. int t ;
  26. scanf("%d",&t);
  27. if (t != -1) Gra[i][j] = t ;
  28. else Gra[i][j] = Max ;
  29. }
  30. }
  31. memset(Exi,0,sizeof(Exi));
  32. memset(Min,0x7f,sizeof(Min));
  33. Min[1] = 0;
  34. for (int i = 1 ; i <= n ; i ++ )
  35. {
  36. int k = 0 ;
  37. for (int j = 1 ; j <= n ; j ++ )
  38. {
  39. if (!Exi[j] && (Min[j] < Min[k])) k = j ;
  40. }
  41. Exi[k] = true ;
  42. for (int j = 1 ; j <= n ; j ++ )
  43. {
  44. if (!Exi[j] && (Gra[k][j] < Min[j])) Min[j] = Gra[k][j] ;
  45. }
  46. }
  47. int tot = 0 ;
  48. for (int i = 1 ; i <= n ; i ++ ) tot += Min[i] ;
  49. printf("%d\n",tot) ;
  50. return 0;
  51. }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值