洛谷 P1111 修复公路

题目背景

A地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车。政府派人修复这些公路。

题目描述

给出A地区的村庄数N,和公路数M,公路是双向的。并告诉你每条公路的连着哪两个村庄,并告诉你什么时候能修完这条公路。问最早什么时候任意两个村庄能够通车,即最早什么时候任意两条村庄都存在至少一条修复完成的道路(可以由多条公路连成一条道路)

输入输出格式

输入格式:
第1行两个正整数N,M

下面M行,每行3个正整数x, y, t,告诉你这条公路连着x,y两个村庄,在时间t时能修复完成这条公路。

输出格式:
如果全部公路修复完毕仍然存在两个村庄无法通车,则输出-1,否则输出最早什么时候任意两个村庄能够通车。

输入输出样例

输入样例#1:
4 4
1 2 6
1 3 4
1 4 5
4 2 3
输出样例#1:
5
说明

N<=1000,M<=100000

x<=N,y<=N,t<=100000

分析:就是一个最小生成树,用并查集跑一边,最小生成树的最大边权就是解。

代码:

var
 p,r:array [1..10001] of longint;
 a:array [1..200001,1..3] of longint;
 n,m,p1,u,v,w,ans,k,i,s:longint;
function find(x:longint):longint;
 var y,root,w:longint;
 begin
 y:=x;
   while p[y]>0 do
    y:=p[y];
   root:=y;
   y:=x;
   while p[y]>0 do
    begin
     w:=p[y];
     p[y]:=root;
     y:=w;
    end;
   find:=root;
 end;

procedure union(x,y:longint);
 var
  u,v:longint;
begin
 u:=find(x);
 v:=find(y);
 if u=v then exit;
 if r[u]<=r[v] then
  begin
   p[u]:=v;
   if r[u]=r[v] then inc(r[v]);
  end
 else p[v]:=u;
end;

procedure qsort(l,r:longint);
  var
    i,j,key,temp:longint;
  begin
    if l>=r then exit;
    i:=l;j:=r;
    key:=a[l+random(r-l+1),3];
    repeat
      while  (a[i,3]<key) do inc(i);
      while  (a[j,3]>key) do dec(j);
      if i<=j then
      begin
        temp:=a[i,1];a[i,1]:=a[j,1];a[j,1]:=temp;
        temp:=a[i,2];a[i,2]:=a[j,2];a[j,2]:=temp;
        temp:=a[i,3];a[i,3]:=a[j,3];a[j,3]:=temp;
        inc(i);dec(j);
      end;
    until i>j;
    qsort(l,j);
    qsort(i,r);
  end;


begin
 readln(n,m);
 for i:=1 to m do
  begin
   readln(u,v,w);
   inc(k);
   a[k,1]:=u;
   a[k,2]:=v;
   a[k,3]:=w;
  end;
 qsort(1,k);
 for i:=1 to k do
  begin
   if find(a[i,1])<>find(a[i,2]) then
    begin
     union(a[i,1],a[i,2]);
     ans:=a[i,3];
    end;
  end;
 for i:=1 to n do
  if find(i)=i then
    inc(s);
 if s<2 then write(ans)
        else write(-1);
end.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值