题面
题目描述
经过特色示范羊村检查,检查组觉得羊村的道路需要重修,破败的道路,会影响到小羊们上学的安全。
村长组织施工队,开始丈量距离,规划施工方案,已经得到了若干建筑物间修建道路的可行方案,共有N个建筑物,和M条可选道路。这些路保证可以将N个建筑相连。
最终方案中,羊村打算修建全球最豪华的全大理石道路,道路可以双向通行,且一体成型,路中无缝隙。为了达到这个设计要求,就必须自建大理石工厂!
大理石工厂建造的难度在于,必须根据其需要生产最大长度的大理石来设计。工厂可以生产出不超过其设计极限的任意长度的大理石。例如,设计长度为100的工厂,可以生产100、90等长度的大理石,但是不能生产长度为101的大理石。
羊村的预算有限,希望你能帮忙规划出一个修路方案,使得工厂的设计规模尽可能小,且可以保证其能生产的大理石可以连通所有羊村的建筑。求出工厂的最小设计规模。
输入
第一行两个整数N和M,N表示羊村中的建筑数量,M表示可以修建的道路数量。
接下来M行,每行三个整数Ai,Bi和Ci,表示从建筑Ai,到建筑Bi,可以修建一条长度为Ci的道路。
注意,建筑编号从1到N,两个建筑之间可能有多条道路。
输出
输出大理石工厂的最小设计规模。
样例输入
3 3
1 2 100
2 3 101
1 3 99
样例输出
100
数据范围限制
30%的数据N<=10,N-1<=M<=100。
100%的数据1<=N<=2000,N-1<=M<=10000,1<=Ai,Bi<=N,1<=Ci<=1000000000。
提示
只要修建1到2,以及1到3的道路,就可以使得3个建筑相互连通,且最大值只有100,只需要建造设计规模为100的大理石工厂,就可以生产出长度为100和99的大理石。
思路
最小生成树模板。
Code
#include<bits/stdc++.h>
using namespace std;
struct node
{
int from,to,dis;
}a[500005];
int n,m,k,tot,f[500005];
void qsort(int l,int r)
{
int i=l,j=r,mid=a[(l+r)/2].dis;
while(i<=j)
{
while(a[i].dis<mid) i++;
while(a[j].dis>mid) j--;
if(i<=j)
{
swap(a[i],a[j]);
i++,j--;
}
}
if(l<j) qsort(l,j);
if(i<r) qsort(i,r);
}
int find(int x)
{
if(x!=f[x]) find(f[x]);
else return x;
}
void unioon(int x,int y)
{
f[find(y)]=find(x);
}
int main()
{
freopen("road.in","r",stdin);
freopen("road.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
f[i]=i;
for(int i=1;i<=m;i++)
scanf("%d%d%d",&a[i].from,&a[i].to,&a[i].dis);
qsort(1,m);
for(int i=1;i<=m;i++)
{
if(k==n-1) break;
if(find(a[i].from)!=find(a[i].to))
{
unioon(a[i].from,a[i].to);
tot=max(tot,a[i].dis);
k++;
}
}
cout<<tot;
return 0;
}