(File IO): input:road.in output:road.out
时间限制: 1000 ms 空间限制: 131072 KB 具体限制
Goto ProblemSet
题目描述
经过特色示范羊村检查,检查组觉得羊村的道路需要重修,破败的道路,会影响到小羊们上学的安全。
村长组织施工队,开始丈量距离,规划施工方案,已经得到了若干建筑物间修建道路的可行方案,共有
N
N
N个建筑物,和
M
M
M条可选道路。这些路保证可以将
N
N
N个建筑相连。
最终方案中,羊村打算修建全球最豪华的全大理石道路,道路可以双向通行,且一体成型,路中无缝隙。为了达到这个设计要求,就必须自建大理石工厂!
大理石工厂建造的难度在于,必须根据其需要生产最大长度的大理石来设计。工厂可以生产出不超过其设计极限的任意长度的大理石。例如,设计长度为
100
100
100的工厂,可以生产
100
、
90
100、90
100、90等长度的大理石,但是不能生产长度为
101
101
101的大理石。
羊村的预算有限,希望你能帮忙规划出一个修路方案,使得工厂的设计规模尽可能小,且可以保证其能生产的大理石可以连通所有羊村的建筑。求出工厂的最小设计规模。
输入
第一行两个整数
N
N
N和
M
,
N
M,N
M,N表示羊村中的建筑数量,M表示可以修建的道路数量。
接下来
M
M
M行,每行三个整数
A
i
,
B
i
Ai,Bi
Ai,Bi和
C
i
Ci
Ci,表示从建筑
A
i
Ai
Ai,到建筑
B
i
Bi
Bi,可以修建一条长度为
C
i
Ci
Ci的道路。
注意,建筑编号从
1
1
1到
N
N
N,两个建筑之间可能有多条道路。
输出
输出大理石工厂的最小设计规模。
样例输入
3 3
1 2 100
2 3 101
1 3 99
样例输出
100
数据范围限制
30
30
30%的数据
N
<
=
10
,
N
−
1
<
=
M
<
=
100
N<=10,N-1<=M<=100
N<=10,N−1<=M<=100。
100
100
100%的数据
1
<
=
N
<
=
2000
,
N
−
1
<
=
M
<
=
10000
,
1
<
=
A
i
,
B
i
<
=
N
1<=N<=2000,N-1<=M<=10000,1<=Ai,Bi<=N
1<=N<=2000,N−1<=M<=10000,1<=Ai,Bi<=N,
1
<
=
C
i
<
=
1000000000
1<=Ci<=1000000000
1<=Ci<=1000000000。
提示
只要修建
1
1
1到
2
2
2,以及
1
1
1到
3
3
3的道路,就可以使得
3
3
3个建筑相互连通,且最大值只有
100
100
100,只需要建造设计规模为
100
100
100的大理石工厂,就可以生产出长度为
100
100
100和
99
99
99的大理石。
解题思路
最小生成树的克鲁斯卡尔发,把累加路径和变成求边权最大值。(我用了并查集)
代码
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<iomanip>
#include<cmath>
using namespace std;
int n,m,k,fa[2010],xx,yy,ans;
struct c{
int x,y,z;
}a[10010];
bool cmp(const c&l,const c&r)
{
return l.z<r.z;
}
int father(int h)
{
while(h!=fa[h])
h=fa[h];
return h;
}
int main(){
freopen("road.in","r",stdin);
freopen("road.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
sort(a+1,a+m+1,cmp);
for(int i=1;i<=n;i++)
fa[i]=i;
for(int i=1;i<=m;i++)
{
xx=father(a[i].x);
yy=father(a[i].y);
if(xx!=yy)
{
ans=max(ans,a[i].z);
fa[xx]=yy;
}
}
printf("%d",ans);
}