Out of Hay 最小生成树的(普莱姆算法)及(克鲁斯卡尔算法)(POJ2395)

描述
奶牛干草用完了,这件可怕的事必须立即补救。贝西打算到其他农场去调查他们的干草状况。有N(2<=N<=2,000)农场(编号1…N);Bessie从农场1开始,她将穿过部分或全部M(1<=M<=10,000)双向道路,其长度不超过1,000,000,000,000,000,000,000,000,000,000,000,000,000,000有些农场可能与不同长度的道路相连。所有农场都以这样或那样的方式连接到农场1。
贝茜想决定她需要多大的水皮。她知道她每隔一段路就需要一盎司水。由于她可以在每个农场获得更多的水,她只关心最长的道路的长度。当然,她计划在农场之间的路线,以尽量减少她必须携带的水量。
帮助贝茜知道她所需要携带的最大水量:假设她选择了尽量减少这一数量的路线,她必须在任何两个农场之间行驶的最长道路的长度是多少?这意味着,当然,她可能会回溯到一条道路上,以尽量减少她要穿越的最长的道路的长度。
输入
*第1行:两个空格分隔的整数,N和M。
*第2…1+M行:I+1行包含三个分隔空格的整数,A_i、B_i和L_i,描述了长度为L_i的A_i到B_i的一条路。
输出量
*第1行:一个整数,它是需要通过的最长道路的长度。
样本输入
3 3
1 2 23
2 3 1000
1 3 43
样本输出
43
该题用prim算法坑很多
该题有重边用prim算法时需要考虑重边
并且该题长度很大需要定义0x7fffffff直接定最大;
代码1(prim算法):672ms

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<vector>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<string>
#include<algorithm>
#include<sstream>
#include<memory>
#include<functional>
using namespace std;
int pre[10010],now[10010],te[10010][10010],n,max1;
void prim()
{
    int sum=0,i,j,min1,t;
    max1=0;
    for(i=1;i<=n;++i)
    {
        now[i]=te[1][i];
        pre[i]=0;
    }
    pre[1]=1;
    for(i=1;i<n;++i)
    {
        min1=0x7fffffff;//数贼大定到顶
        for(j=1;j<=n;++j)
        {
            if(pre[j]==0&&now[j]<min1)
            {
                min1=now[j];
                t=j;
            }
        }
        if(max1<min1)
            max1=min1;
        pre[t]=1;
        for(j=1;j<=n;++j)
            if(pre[j]==0&&now[j]>te[t][j])
                now[j]=te[t][j];
    }
}
int main()
{
    int m,x,y,i,z,j;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        for(i=1;i<=n;++i)
            for(j=1;j<=n;++j)
                te[i][j]=0x7fffffff;
        for(i=1;i<=m;++i)
        {
            cin>>x>>y>>z;
            if(te[x][y]>z)
                te[x][y]=te[y][x]=z;//必须判这个,路径可能不止一条,取最小(就是去重边)
        }
        prim();
        cout<<max1<<endl;
    }
    return 0;
}

代码2(kruskal算法):625ms

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<vector>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<string>
#include<algorithm>
#include<sstream>
#include<memory>
#include<functional>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a));
#define ll long long int
int pre[10010],n,m;
struct node1
{
    int from;
    int to;
    int w;
}node[10010];
int zhaodie(int son)
{
    int deson,dad;
    deson=son;
    while(son!=pre[son])
        son=pre[son];
    while(deson!=pre[deson])
    {
        dad=pre[deson];
        pre[deson]=son;
        deson=dad;
    }
    return son;
}
bool cmp(node1 x,node1 y)
{
    return x.w<y.w;
}
void kruskal()
{
    sort(node,node+m,cmp);
    int max1=0,js=0,i,dad1,dad2;
    for(i=0;i<m;++i)
    {
        dad2=zhaodie(node[i].from);
        dad1=zhaodie(node[i].to);
        if(dad1!=dad2)
        {
            max1=max(max1,node[i].w);
            pre[dad1]=dad2;
            ++js;
            if(js==n-1)
                break;
        }
    }
    cout<<max1<<endl;
}
int main()
{
    int i;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        for(i=1;i<=n;++i)
            pre[i]=i;
        for(i=0;i<m;++i)
        {
            cin>>node[i].from>>node[i].to>>node[i].w;
        }
        kruskal();
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值