【最短路】造路行动

题目:造路行动

题目描述

学校某日突发奇想,要造个小公园。但是,公园造造简单,最麻烦的就是路了。学校张榜:谁设计一个方案,材料费最小,那么,他就获得1000奖学金。鄙人想去,但是作业铺天盖地,根本没时间啊。只好到网上来求助……
各路英雄,帮帮忙吧。

输入格式

第1行,二个数,N,M。N表示公园有N个景点,M表示规划的可以造路的路的条数
接下来M行,每行3个数:X,Y,A。表示第X个景点和第Y个景点之间可以造路,材料费为A。(第X个景点和第Y个景点之间可以造路,也就是说第Y个景点和第X个景点之间也可以造路)。
当然,不会出现孤立的景点。
数据范围:0 <N<=1000,0 <M<=N*(N-1),0 <X,Y<=N,0 <A<32768。
输出格式

一个数,表示最少的材料费。

样例输入

8 13
1 7 1
1 2 9
1 6 9
2 8 2
2 3 9
3 8 3
3 4 9
4 8 4
4 5 9
5 7 5
5 6 9
6 7 6
7 8 7
样例输出

28

-------------------------------

kruskal+并查集

-------------------------

调试的技巧

1.检查数据范围是否正确

2.检查变量是否打错

3.检查程序是否会超时。

-----------------------

type
  node=record
         x,y:longint;
         cost:longint;
       end;
var
  n,m:longint;
  map:array[1..1000000]of node;
  f:array[1..10000]of longint;
  ans:longint;
  
procedure init;
begin
  assign(input,'rq193.in');
  assign(output,'rq193.out');
  reset(input); rewrite(output);
end;

procedure terminate;
begin
  close(input); close(output);
  halt;
end;

procedure qsort(s,t:longint);
var
  i,j:longint;
  x:longint;
  tem:node;
begin
  i:=s; j:=t;
  x:=map[(s+t)shr 1].cost;
  repeat
    while x<map[j].cost do dec(j);
    while map[i].cost<x do inc(i);
    if i<=j then
      begin
        tem:=map[i];
        map[i]:=map[j];
        map[j]:=tem;
        inc(i); dec(j);
      end;
  until i>j;
  if s<j then qsort(s,j);
  if i<t then qsort(i,t);
end;

function find(x:longint):longint;
begin
  if x<>f[x] then begin f[x]:=find(f[x]); exit(f[x]); end
             else exit(x);
end;

procedure merge(x,y:longint);
begin
  x:=find(x);
  y:=find(y);
  f[x]:=y;
end;

procedure main;
var
  i:longint;
  num:longint;
begin
  read(n,m);
  for i:=1 to m do read(map[i].x,map[i].y,map[i].cost);
  for i:=1 to n do f[i]:=i;
  qsort(1,m);
  num:=0; ans:=0;
  for i:=1 to n-1 do
    begin
      while true do
        begin
          inc(num);
          if find(map[num].x)=find(map[num].y) then continue
          else begin
                 inc(ans,map[num].cost);
                 merge(map[num].x,map[num].y);
                 break;
               end;
        end;
    end;

  writeln(ans);
end;

begin
  init;
  main;
  terminate;
end.


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值