poj 1789 Truck History(kruskal算法实现)

23 篇文章 0 订阅
15 篇文章 0 订阅

怎么我的算法时间和空间都这么就,别人的kruskal还是比较快的! 去学习一下!

/*kruskal算法*/
#include <iostream>
//#include <fstream>
#include <algorithm> 
using namespace std;
#define MAX 2001
#define min(a,b)  (a-b<0?a:b)

/*45612K	1563MS*/
typedef struct _node
{
        int x,y;
        int weight;
}node;

int n;
char a[MAX][8];
int sum;
//fstream fin;

void kruskal(node *a,int index);
int GetDis(int x,int y);
int cmp(const void *a,const void *b);

int main()
{
    //fin.open("1789.txt",ios::in);
    while(cin>>n)
    {
         if(n==0)  break;
         sum=0;
         for(int i=0;i<n;i++)
            cin>>a[i];
         //计算边的信息
         node *a=new node[n*n]; 
         node temp;
         int index=0;
         for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
            {
                    temp.x=i;
                    temp.y=j;
                    temp.weight=GetDis(i,j);
                    a[index++]=temp;
            }

         kruskal(a,index);
         cout<<"The highest possible quality is 1/"<<sum<<"."<<endl; 
         delete []a;        
    }
    system("pause");
    return 0;
}

int GetDis(int x,int y)
{
    int count=0;
    for(int i=0;i<7;i++)
       if(a[x][i]!=a[y][i])
         ++count;

    return count;
}

int cmp(const void *a,const void *b)
{
    node a1=*(node *)a;
    node b1=*(node *)b;
    return (a1.weight-b1.weight);
}

void kruskal(node *a,int index)
{
     //排序
     qsort(a,index,sizeof(node),cmp);
     int *s=new int[n];
     memset(s,0,sizeof(int)*n);
     int parts=0;  //分支数 
     for(int i=0;i<index;i++)
     {
             if(a[i].weight==0)  continue;
             int u,v;
             u=a[i].x;v=a[i].y;
             //判断u,v在位置上
            if(!s[u]&&!s[v]) 
             {
                  parts++;
                  s[u]=parts;
                  s[v]=parts;
                  sum+=a[i].weight;
             }
             else  if(s[u]&&!s[v])
             {
                   s[v]=s[u];
                   sum+=a[i].weight;
             }
             else if(s[v]&&!s[u])
             {
                   s[u]=s[v];
                   sum+=a[i].weight;
             }
             else
             {
                 if(s[u]!=s[v])  //不在同一个分支上 
                 {
                       //计算最小的分支
                       int min=s[u];
                       int max=s[v];
                       if(s[v]>s[u])
                       {
                          min=s[v];
                          max=s[u];
                       } 
                       for(int j=0;j<n;j++)
                       {
                           if(s[j]==max)
                             s[j]=min;
                           if(s[j]>max)
                             s[j]--;
                       }
                       parts--; 
                       sum+=a[i].weight;
                 }
             }
     }
     
     delete []s;
         
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值