poj 1789 Truck History(prim算法)

未优化版本

/*prim算法实现*/ 
#include <iostream>
//#include <fstream>
using namespace std;
#define MAX 2001
#define INF 0xffff
/*15988K	500MS*/
//var
int n;
char a[MAX][10];
int sum;//代表生成树的长度
int m[MAX][MAX];
//fstream fin;

//fuction
int  GetDis(int x,int y);
void cal();
void prim(int u);

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];
         //初始化距离为0
         memset(m,0,sizeof(m));
         
         cal();
         prim(0);
         cout<<"The highest possible quality is "<<"1/"<<sum<<"."<<endl;
    }
    system("pause");
    return 0;
}

//计算每一对类型的距离 
void cal()
{
     for(int i=0;i<n;i++)
     {
             for(int j=0;j<n;j++)
                 m[i][j]=GetDis(i,j);    
     }
}

//计算一对顶点的代码 
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;
} 

//prim算法
void prim(int u)
{
     int *lowset=new int[n];
     bool *s=new bool[n];
     
     //初始化
     for(int i=0;i<n;i++)
     {
          if(u!=i)
          {
               lowset[i]=m[u][i];
               s[i]=false;
          }   
    }

    int q;
    s[u]=true;
    for(int i=0;i<n-1;i++)
    {
            //找到最小的lowest
            int min=INF;
            for(int j=0;j<n;j++)
            {
                  if(lowset[j]<min&&(!s[j]))
                  {
                       q=j;
                       min=lowset[j];
                  } 
            } 
            //更新s,lowest
            sum+=min;
            s[q]=true;
            for(int j=0;j<n;j++)
            {
                   if(m[q][j]<lowset[j]&&(!s[j]))
                   {
                        lowset[j]=m[q][j];
                   }
            } 
    } 
    
    delete []lowset;
    delete []s;
} 

优化版本

/*prim算法*/
#include <iostream>
//#include <fstream>
using namespace std;
#define MAX 2001
#define INF 0xffff

/*356K	407MS*/
int n;
char a[MAX][8];
int sum;
//fstream fin; 

void prim(int u);
int GetDis(int x,int y);

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];
         prim(0);
         cout<<"The highest possible quality is "<<"1/"<<sum<<"."<<endl;
    }  
    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;
}

void prim(int u)
{
     int *lowset=new int[n];
     bool *s=new bool[n];
     //初始化程序
     
     for(int i=0;i<n;i++)
     {
             if(u!=i)
             {
                     lowset[i]=GetDis(u,i);
                     s[i]=false;
             }
     } 
     
     int q;
     s[u]=true;
     for(int i=0;i<n-1;i++)
     {
             //计算出最小值
             int min=INF;
             for(int j=0;j<n;j++)
             {
                  if(min>lowset[j]&&!s[j])
                  {
                      q=j;
                      min=lowset[j];
                  }
             } 
             s[q]=true;
             sum+=min;
             //更新lowset
             for(int j=0;j<n;j++)
             {
                     if(GetDis(q,j)<lowset[j]&&!s[j])
                         lowset[j]=GetDis(q,j);
             } 
     }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值