POJ 1789 Truck History (Prim 稠密图上的MST问题)

 

第一次敲prim算法

保存了路径的代码:没有将lowcost和mst合并

#include <cstdio>
#include <string.h>
//Prim
const int maxn=2010;
const int inf=10000;
int lowcost[maxn],mst[maxn];
int map[maxn][maxn];
int n,m;
char str[maxn][10];
void Prim (int u0)//从
{
    int i,j;
    int ans=0;
    for (i=1 ; i<=n ; ++i)
     lowcost[i]=map[u0][i],mst[i]=u0;
    mst[u0]=-1;
    for (i=1 ; i<n ; ++i)
    {
        int min=inf;
        int v=-1;
        for (j=1 ; j<=n ; ++j)
         if(mst[j]!=-1 && lowcost[j]<min)//找到mst不为-1  且lowcost最小的边
            v=j , min=lowcost[j];
        if(v!=-1)
        {
            //printf("%d %d %d\n",v,mst[v],lowcost[v]);
            mst[v]=-1;//将v加入T中
            ans+=lowcost[v];
            for (j=1 ; j<=n ; ++j)
             if(mst[j]!=-1 && map[v][j]<lowcost[j])//更新新加入的v与原来的点的最短路
              lowcost[j]=map[v][j],mst[j]=v;
        }
    }
    printf("The highest possible quality is 1/%d.\n",ans);
}

int main ()
{
    int i,j,k;
    int u,v,w;
    while (scanf( "%d" , &n )!=EOF && n)
    {
        memset (map , 0 , sizeof(map));
        for (i=1 ; i<=n ; ++i)
        {
            scanf("%s",str+i);
        }
        for (i=1 ; i<=n ; ++i)
         for (j=i ; j<=n ; ++j)
         {
                if(i==j)map[i][j]=0;
                else
                {
                    for (k=0 ; k<7 ; ++k)
                    if(str[i][k]!=str[j][k])++map[i][j];
                    map[j][i]=map[i][j];
                }
         }
        Prim(1);
    }
    return 0;
}

不保存路径的方法:

#include <cstdio>
#include <string.h>
//Prim
const int maxn=2010;
const int inf=10000;
int mst[maxn];
int map[maxn][maxn];
int n,m;
char str[maxn][10];
void Prim (int u0)//
{
    int i,j;
    int ans=0;
    for (i=1 ; i<=n ; ++i)
     mst[i]=map[u0][i];
    mst[u0]=-1;
    for (i=1 ; i<n ; ++i)
    {
        int min=inf;
        int v=-1;
        for (j=1 ; j<=n ; ++j)
         if(mst[j]!=-1 && mst[j]<min)v=j , min=mst[j];
        if(v!=-1)
        {
            //printf("%d %d %d\n",v,mst[v],lowcost[v]);
            ans+=mst[v];
            mst[v]=-1;//将v加入T中
            for (j=1 ; j<=n ; ++j)
             if(mst[j]!=-1 && map[v][j]<mst[j])//更新新加入的v与原来的点的最短路
              mst[j]=map[v][j];
        }
    }
    printf("The highest possible quality is 1/%d.\n",ans);
}

int main ()
{
    int i,j,k;
    int u,v,w;
    while (scanf( "%d" , &n )!=EOF && n)
    {
        memset (map , 0 , sizeof(map));
        for (i=1 ; i<=n ; ++i)
        {
            scanf("%s",str+i);
        }
        for (i=1 ; i<=n ; ++i)
         for (j=i ; j<=n ; ++j)
         {
                if(i==j)map[i][j]=0;
                else
                {
                    for (k=0 ; k<7 ; ++k)
                    if(str[i][k]!=str[j][k])++map[i][j];
                    map[j][i]=map[i][j];
                }
         }
        Prim(1);
    }
    return 0;
}

 

2个方法 时间上没什么太大区别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值