【HDU 1233】【并查集】【最小生成树】还是畅通工程

第一种是最小生成树的,题意应该也是用这个吧,可以a的。

第二种用并查集,讲联通的保存一个祖先就可以了。

两种代码如下。

#include "stdio.h"
#include "string.h"
int main(int argc, char const *argv[])
{
    int n,m,i,j,k,min,t1,t2,t3;
    int e[105][105],dis[105],book[105]={0};
    int inf=99999999;
    int count=0,sum=0;
    while(~scanf("%d",&n) && n)
    {   //if(n==1) printf("0\n");
        m=n*(n-1)/2;
        count=0;sum=0;
        memset(e,0,sizeof(e));
        memset(book,0,sizeof(book));
        memset(dis,0,sizeof(dis));
        for ( i = 1; i <= n; ++i)
            for (j = 1; j <= n; ++j)
                if(i==j) e[i][j]=0;
                else e[i][j]=inf;
        for ( i = 1; i <= m; ++i)
        {
            scanf("%d %d %d",&t1,&t2,&t3);
            e[t1][t2]=t3;
            e[t2][t1]=t3;
        }
        for (i = 1; i <= n; ++i)
            dis[i]=e[1][i];

        book[1]=1;
        count++;
        while(count<n)
        {
            min=inf;
            for (i = 1; i <= n; ++i)
            {
                if(book[i]==0 && dis[i]< min)
                {
                    min=dis[i];j=i;
                }
            }
            book[j]=1;count++;sum+=dis[j];

            for (k= 1; k <= n; ++k)
            {
                if(book[k]==0 && dis[k]>e[j][k])
                    dis[k]=e[j][k];
            }
        }
                    printf("%d\n",sum);

    }
    return 0;
}


#include "stdio.h"
#include "stdlib.h"
#include "algorithm"
using namespace std;//上次做的时候用的prim最小生成树,那这次并查集试着做一下好了。
int se[100];//SE放祖先,set放路径
struct node
{
   int i;
   int j;
   int k;      
 }set[5005];

int cmp(node a,node b)
{  
   return a.k<b.k;
}

int find(int i) 
{     
       if(se[i]==i)
        return i;
    else{
        se[i]=find(se[i]);
        return se[i];
    }
} 

void join(int a,int b) 
{      
    int x,y;      
    x=find (a);      
    y=find (b);      
    if(x != y)        
       se[x]=y;     
}

int main( )
{    
   int m;   
   while(scanf("%d",&m),m)    
   {   
      int n=(m*(m-1))/2;      
      for( int i=1; i<=m ; i++)       
         se[i]=i;            
      for(int i=0;i<n;i++)   
        scanf("%d%d%d",&set[i].i,&set[i].j,&set[i].k);          
     sort(set,set+n,cmp);   
          
    int d,e,f,sum=0;  
    for(int i=0;i<n;i++)      
    {       
        d=set[i].i;        
        e=set[i].j;    
        f=set[i].k;            
        if(find(d)!=find(e))           
       {           
          sum+=f;           
          join(d,e);         
        } 
     }
     printf("%d\n",sum);    
   }   
   return 0;
} 


你可能感兴趣的:(数据结构,c,水题)