Out of Hay 饲料没了

Description

牛们的饲料吃完了,这是一个必须马上解决的严重问题。 Bessie想去其他农场看看他们的饲料情况。总共有N (2 <= N <= 2,000)个农场,编号1到N,Bessie打算到每个农场去看看。Bessie从编号1的农场出发,她将穿过部分或者是全部的M条双向道路,这些道路把所有农场连接了起来,并且每条路的长度不超过1,000,000,000米。有的农场间可能有多条不同长度的道路相连。从1号农场出发可以到达所有其他农场。 

Bessie想知道她需要携带多大的水壶。她每走1米的路,她就会喝掉1升的水。因为她在每个农场都可以把水壶灌满,所以她只需要考虑其中最长的一条道路。因此,她想事先设计出一条路径,使她能够达到所有的农场,并且使她携带的水尽可能少。请你帮Bessie算出她最少需要携带多大的水壶。

Input

第一行,两个整数N和M(M<=10000) 
接下来M行,每行三个整数X,Y,Z,表示农场X与农场Y之间有条长度为Z的道路

Output

一个整数,表示Bessie携带的水壶最少要能装多少升水。

Sample Input

 

3 3 
1 2 23 
2 3 1000 
1 3 43

 

Sample Output

 

43
【分析】

算法:最小生成树 
    最小生成树的算法通常是Prim或Kruskal,而Kruskal有个很好的性质,就是求出来的生成树最长的那条边是最短的。这个性质显然成立,因为Kruskal是基于贪心算法的。 
    那么再看看这道题,就变成了裸的Kruskal。 


【代码】
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
struct node{
   int x,y,z;
}edge[10005];
int N,M,father[2005];
void _in(int &x)
{
   char t;
   t=getchar();
   while(t<'0'||'9'<t) t=getchar();
   for(x=t-'0',t=getchar();'0'<=t&&t<='9';x=x*10+t-'0',t=getchar());
}
int _getfather(int x)
{
   if(x!=father[x]) father[x]=_getfather(father[x]);
   return father[x];
}
void _qst_edge(int l,int r)
{
   int i=l,j=r,mz=edge[(i+r)>>1].z;
   while(i<=j)
   {
       while(edge[i].z<mz) i++;
       while(edge[j].z>mz) j--;
       if(i<=j)
       {
           swap(edge[i],edge[j]);
           i++;j--;
       }
   }
   if(l<j) _qst_edge(l,j);
   if(i<r) _qst_edge(i,r);
}
void _kruskal()
{
   int fx,fy,cnt,k,ans;
   cnt=k=ans=0;
   while(cnt<N-1)
   {
       k++;
       fx=_getfather(edge[k].x);
       fy=_getfather(edge[k].y);
       if(fx!=fy)
       {
           father[fx]=fy;
           ans=max(ans,edge[k].z);
           cnt++;
       }
   }
   printf("%d\n",ans);
}
void _init()
{
   _in(N);_in(M);
   for(int i=1;i<=M;i++)
   {
       _in(edge[i].x);
       _in(edge[i].y);
       _in(edge[i].z);
   }
   _qst_edge(1,M);
   for(int i=1;i<=N;i++)
       father[i]=i;
}
void _solve()
{
   _kruskal();
}
int main()
{
   _init();
   _solve();
   return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值