Vijos P1045Kerry 的电缆网络

7 篇文章 0 订阅
3 篇文章 0 订阅

Hello friend.

题目如下

描述
Kerry 是德国的一位电缆商人。因联合国脱贫计划的邀请,他准备负责在土鲁齐亚埃萨亚克斯乌托斯邦建立电缆网络,以满足这个国家的用电需求。当然,现在土鲁齐亚埃萨亚克斯乌托斯邦没有任何电缆。已知土鲁齐亚埃萨亚克斯乌托斯邦一共有n个城镇,已经编号为1到n。其中任意两个城镇可能有一条路,也可能没有。如果两个城镇之间有一条路pi,那么这条路有一个长度si,则Kerry可以在这两个城市之间建立一条电缆线,电缆线的长度也就是这条路的长度si。
现在Kerry准备了s长的电缆线,电缆线可以任意拆断,拆断不损失任何电缆线。他需要将土鲁齐亚埃萨亚克斯乌托斯邦所有城镇都能够连入这个电缆网络。那么,Kenny能不能使用这s长度的电缆线完成这项工作;如果能够完成,那么Kerry最少耗用多少长度的电缆线呢?
格式
输入格式

第一行一个正实数S;
第二行一个正整数n;
接下来一共有m行,第i行有两个整数xi,yi和一个实数si,表示编号为xi个村庄和编号为yi个村庄之间有一条路,路的长度为si。
输入保证xi不等于yi,两个城镇之间不会有两条路。
输出格式

若能够完成(建立这样的电缆网络),则输出(其中代表最少的电缆线长度,保留两位小数):
Need miles of cable
否则输出:
Impossible
样例1
样例输入1

100.0
4
1 2 2.0
1 3 4.2
1 4 6.7
3 4 4.0
2 4 10.0
样例输出1

Need 10.20 miles of cable
限制
各个测试点3s
提示
1<=n,m<=100000

分析

对于该题很显然是一个纯粹的最小生成树的题目,只要对其进行一遍Kruscal即可通过,同时记录加入了多少条边,若加的边数等于节点数-1则说明所有的顶点都已联通,否则输出Impossible。

代码如下

program p1045;
type rec=record
      s,e:longint;
      v:real;
     end;
var n,m,sum:longint;
    len,cost:real;
    map:array[1..100000] of rec;
    i,j,k:longint;
    father:array[1..100000] of longint;
    rank:array[1..100000] of longint;
procedure qsort(i,j:longint);
var l,r:longint;
    mid:real;
    temp:rec;
begin
 l:=i;
 r:=j;
 mid:=map[(l+r)>>1].v;
 while l<=r do
  begin
   while map[l].v<mid do inc(l);
   while map[r].v>mid do dec(r);
   if l<=r then
    begin
     temp:=map[l];
     map[l]:=map[r];
     map[r]:=temp;
     inc(l);
     dec(r);
    end;
  end;
 if l<j then qsort(l,j);
 if i<r then qsort(i,r);
end;

function find(x:longint):longint;
begin
 if father[x]=x
  then exit(x);
 father[x]:=find(father[x]);
 exit(father[x]);
end;

procedure unite(a,b:longint);
var fa,fb:longint;
begin
 fa:=find(father[a]);
 fb:=find(father[b]);
 if rank[fa]>rank[fb]
  then
   father[fb]:=fa
  else
   father[fa]:=fb;
end;

begin
 readln(len);
 readln(n);
 m:=0;
 while not eof do
  begin
   inc(m);
   with map[m] do
    readln(s,e,v);
  end;
 qsort(1,m);
 for i:=1 to m do
  begin
   father[i]:=i;
   rank[i]:=1;
  end;
 for i:=1 to m do
  begin
   if find(map[i].s)<>find(map[i].e)
    then
     begin
      unite(map[i].s,map[i].e);
      inc(sum);
      cost:=cost+map[i].v;
     end;
  end;
 if (cost>len) or (sum<>(n-1))
  then write('Impossible')
  else write('Need ',cost:0:2,' miles of cable');
end.

附上评测地址

vijos p1045

每日一句

一个人总要走陌生的路,看陌生的风景,听陌生的歌,然后在某个不经意的瞬间,你会发现,原本是费尽心机想要忘记的事情真的就那么忘记了。

或许忘记了却会更加珍惜过往失去的一切,只希望珍惜现在以及把握未来。

珍惜过往,往事如风

我会永远珍惜过往的一切。即使已经回不过去过往,即使脚步阻挡不了时光的流逝!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值