B1682 [Usaco2005 Mar]Out of Hay 干草危机

题目描述

Bessie 计划调查 NN2 \le N \le 20002N2000)个农场的干草情况,它从 11 号农场出发。农场之间总共有 MM1 \leq M \leq 10^41M104)条双向道路,所有道路的总长度不超过 10^9109 。有些农场之间存在着多条道路,所有的农场之间都是连通的。

Bessie 希望计算出该图中最小生成树中的最长边的长度。


输入格式

第 1 行输入两个整数 NN 和 MM; 接下来 MM 行,每行输入三个整数,表示一条道路的起点终点和长度。


输出格式

一个整数,表示最小生成树中的最长边的长度。


样例输入

Copy to Clipboard
3 3
1 2 23
2 3 1000
1 3 43


样例输出

Copy to Clipboard
43

由 1 到达 2,需要经过长度 23 的道路;回到 1 再到 3,通过长度 43 的道路.最长道路为 43


提示

没有写明提示


题目来源

Silver

 

求最小生成树,prim算法或者克鲁斯卡尔算法。

克鲁斯卡尔:

复制代码
#include<iostream>
#include<algorithm>
using namespace std;
struct v
{
    int begin;
    int end;
    int val;
}; 
bool cmp(v r1,v r2)
{
    return r1.val<r2.val;
}
int main()
{
    int N,M,num=0,begin,end,elem,k,mx=0;
    cin>>N>>M;
    int flag[N+5];
    v r[M+5],minr[M+5];
    for(int i=0;i<M;i++)
    {
        cin>>r[i].begin>>r[i].end>>r[i].val;
    } 
    for(int i=0;i<N;i++)//每个顶点作不同标记 
    {
        flag[i]=i;
    }
    sort(r,r+M,cmp);//按边权升序排序 
    for(int i=0;i<M;i++)//遍历所有边 
    {
        begin=r[i].begin-1;
        end=r[i].end-1;//找到当前两个顶点在flag数组中的位置下标 
        if(flag[begin]!=flag[end])
        {
            minr[num]=r[i];//记录这一条边的数据,加入最小生成树 
            num++;//计数+1 
            elem=flag[end];
            //将新加入生成树定点标记全部改为一样的 
            for(k=0;k<N;k++)
            if(flag[k]==elem)
            flag[k]=flag[begin];
            //若选择的边数量和顶点数差1,则最小生成树已经构造完成 
            if(num==N-1)
            break;
        }
    } 
    //取最小生成树的最长边 
    for(int i=0;i<N-1;i++)
    mx=max(mx,minr[i].val);
    cout<<mx<<endl;
}
复制代码

prim:prim一直有四个测试点过不了。leedcode

复制代码
#include<iostream>
#include<cstring>
#include<algorithm>
#define MAX 1000000005
using namespace std;
int N,M,c=1;//c是计数器 
int a[2001][2001];
long long dis[2001];
void prim(int v){
    int lowcost[2001],closest[2001];
    int mincost,i,j,k;//k记录最近顶点的编号 
    for(i=1;i<=N;i++)
    {
        lowcost[i]=a[v][i];
        closest[i]=v;
    }//初始化lowcost,closest数组
    for(i=1;i<N;i++)//n-1次
    {
        mincost=MAX;
        for(j=1;j<=N;j++)
        if(lowcost[j]!=0&&lowcost[j]<mincost)
        {
            mincost=lowcost[j];
            k=j;
        }
        lowcost[k]=0;
        dis[c++]=mincost;
        for(j=1;j<=N;j++)
        if(a[k][j]!=0&&a[k][j]<lowcost[j])
        {
            lowcost[j]=a[k][j];
            closest[j]=k;
        }//refresh lowcost[],closest[] 
     } 
}
int main()
{
    memset(a,MAX,sizeof(a));
    cin>>N>>M;
    int b,e,l;
    for(int i=1;i<=M;i++)
    {
        cin>>b>>e>>l;
        a[b][e]=l;
        a[e][b]=l;
    }
    for(int i=1;i<=N;i++)
    a[i][i]=0;//初始化 
    prim(1);
    long long int maxdis=0;
    for(int i=1;i<=N;i++)
    {
        if(maxdis<(long long)dis[i])
        maxdis=dis[i];
    }
    cout<<maxdis<<endl;
    //sort(dis+1,dis+N);
    //cout<<dis[N-1]<<endl;
    return 0;
}
复制代码

 

posted @   辛夸高岭桂  阅读(90)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示