网络

您被分配设计广泛区域中某些点之间的网络连接。您将获得该区域中的一组点,以及可连接成对点的电缆的一组可能路线。对于两点之间的每条可能路线,您将获得连接该路线上的点所需的电缆长度。请注意,两个给定点之间可能存在许多可能的路径。假设给定的可能路线(直接或间接)连接该区域中的每两个点。
您的任务是为该区域设计网络,以便在每两个点之间存在连接(直接或间接)(即,所有点都是互连的,但不一定是通过直接电缆),并且总长度为用过的电缆很小。输入输入文件由许多数据集组成。每个数据集定义一个必需的网络。集合的第一行包含两个整数:第一行定义给定点的数量P,第二行定义点之间给定路径的数量R. 以下R行定义了点之间的给定路线,每条线给出三个整数:前两个数字标识点,第三个给出路线的长度。数字用空格分隔。仅给出一个数字P = 0的数据集表示输入的结束。数据集用空行分隔。
最大点数为50.给定路线的最大长度为100.可能的路线数量不受限制。节点用1和P(含)之间的整数标识。两个点i和j之间的路线可以给出为ij或j i。
产量对于每个数据集,在单独的行上打印一个数字,该行显示用于整个设计网络的电缆的总长度。样本输入
1 0

2 3
1 2 37
2 1 17
1 2 68

3 7
1 2 19
2 3 11
3 1 7
1 3 5
2 3 89
3 1 91
1 2 32

5 7
1 2 5
2 3 7
2 4 8
4 5 11
3 5 10
1 5 6
4 2 12

0样本输出
0
17
16
26
解题思路:要连接所有的线,又要最短,这就需要最小生成树的概念。
现将短的路径选出来,这就需要排序,然后再判断是否有回路,用并查集检查。最后将所选边加起来。因为无回路的树n个点有n-1条边,所以到n-1退出。

#include<stdio.h>
int a[5000];
struct edge
{
    int a;
    int b;
    int c;
};
struct edge e[5000];
void quicksort(int left,int right)
{
    int i,j;
    struct edge t;
    i=left;
    j=right;
    if(i>j)return ;
    while(i!=j)
    {
        while(i<j&&e[j].c>=e[left].c)
            j--;
        while(i<j&&e[i].c<=e[left].c)
            i++;
        if(i<j)
        {
            t=e[i];
            e[i]=e[j];
            e[j]=t;
        }
    }
    t=e[i];
    e[i]=e[left];
    e[left]=t;
    quicksort(left,i-1);
    quicksort(i+1,right);
    return ;
}
int f(int v)
{
    if(a[v]==v)return v;
    else
    {
        a[v]=f(a[v]);
        return a[v];
    }
}
int getf(int u,int v)
{
    int t1,t2;
    t1=f(u);
    t2=f(v);
    if(t1!=t2)
    {
        a[t2]=t1;
        return 1;
    }
    return 0;
}
int main()
{
    int sum,i,j,p,r,flag;
    while(scanf("%d",&p)!=EOF)
    {
        if(p==0)break;
        sum=0;
        flag=0;
        scanf("%d",&r);
        for(i=1;i<=p;i++)
            a[i]=i;
        for(i=1;i<=r;i++)
        {
            scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].c);
        }
        quicksort(1,r);
        for(i=1;i<=r;i++)
        {
            if(getf(e[i].a,e[i].b))
            {
                sum+=e[i].c;
                flag++;
            }
            if(flag==p-1)
                break;
        }
        printf("%d\n",sum);
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值