最小生成树(卡鲁斯卡尔)

http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2896

最小生成树:n个顶点n-1条边

本题因为有50000个点,所以只能用Kuscal

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int bin[50001];
struct node
{
    int x,y,z;
}q[200001];
int cmp(const void *a,const void *b)
{
    return (*(struct node *)a).z>(*(struct node *)b).z?1:-1;
}
int findx(int x)
{
    int r=x;
    while(r!=bin[r])
    {
        r=bin[r];
    }
    int j=x,k;
    while(j!=r)
    {
        k=bin[j];
        bin[j]=r;
        j=k;
    }
    return r;
}
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=0;i<=n;i++)
        bin[i]=i;
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].z);
        }
        qsort(q,m,sizeof(q[0]),cmp);
        int x,y,l=0,sum=0;
        for(int i=0;i<m;i++)
        {
            x=findx(q[i].x);
            y=findx(q[i].y);
            if(x!=y)
            {
                bin[x]=y;
                sum=sum+q[i].z;
                l++;
            }
            if(l==n-1)
            break;
        }
        printf("%d\n",sum);
    }
    return 0;
}

 

  1. #include <iostream>  
  2. #include <stdio.h>  
  3. #include <string.h>  
  4. #include <stdlib.h>  
  5. #include <math.h>  
  6. using namespace std;  
  7. int n,m,tt;  
  8. struct node  
  9. {  
  10.     int x,y,w;  
  11. }edge[200001];  
  12. int bin[50002];  
  13. void add(int u,int v,int w1)  
  14. {  
  15.     edge[tt].x=u;  
  16.     edge[tt].y=v;  
  17.     edge[tt].w=w1;  
  18.     tt++;  
  19. }  
  20. int cmp(const void *a,const void *b)  
  21. {  
  22.     return (*(struct node *)a).w-(*(struct node *)b).w;  
  23. }  
  24. int findx(int x)  
  25. {  
  26.     int r=x;  
  27.     while(r!=bin[r])  
  28.         r=bin[r];  
  29.     int j,k;  
  30.     j=x;  
  31.     while(j!=r)  
  32.     {  
  33.         k=bin[j];  
  34.         bin[j]=r;  
  35.         j=k;  
  36.     }  
  37.     return r;  
  38. }  
  39. void merge(int fx,int fy)  
  40. {  
  41.    // int fx=findx(x);  //节约时间
  42.    //int fy=findx(y);  //节约时间
  43.     if(fx!=fy)  
  44.         bin[fx]=fy;  
  45. }  
  46. void Kuscal()  
  47. {  
  48.     int sum=0;  
  49.     int ll=1;//最小生成树n-1条边  
  50.     int i=0;  
  51.     while(ll<n)  
  52.     {  
  53.         if(findx(edge[i].x)!=findx(edge[i].y))  
  54.         {  
  55.             merge(edge[i].x,edge[i].y);  
  56.             sum=sum+edge[i].w;  
  57.             ll++;  
  58.         }  
  59.         i++;  
  60.     }  
  61.     printf("%d\n",sum);  
  62.   
  63. }  
  64. int main()  
  65. {  
  66.     int u,v,w1;  
  67.     while(scanf("%d%d",&n,&m)!=EOF)  
  68.     {  
  69.         tt=0;  
  70.         for(int i=1;i<=n;i++)  
  71.             bin[i]=i;  
  72.         while(m--)  
  73.         {  
  74.             scanf("%d%d%d",&u,&v,&w1);  
  75.             add(u,v,w1);  
  76.         }  
  77.         qsort(edge,tt,sizeof(edge[0]),cmp);  
  78.        Kuscal();  
  79.     }  
  80.     return 0;  
  81. }  
  82.   
  83.   
  84.    
  85.   

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值