您的位置:首页 > 其它

洛谷 2330 最小生成树

2017-03-11 10:20 218 查看


题目描述

城市C是一个非常繁忙的大都市,城市中的道路十分的拥挤,于是市长决定对其中的道路进行改造。城市C的道路是这样分布的:城市中有n个交叉路口,有些交叉路口之间有道路相连,两个交叉路口之间最多有一条道路相连接。这些道路是双向的,且把所有的交叉路口直接或间接的连接起来了。每条道路都有一个分值,分值越小表示这个道路越繁忙,越需要进行改造。但是市政府的资金有限,市长希望进行改造的道路越少越好,于是他提出下面的要求:

1.改造的那些道路能够把所有的交叉路口直接或间接的连通起来。

2.在满足要求1的情况下,改造的道路尽量少。

3.在满足要求1、2的情况下,改造的那些道路中分值最大的道路分值尽量小。

任务:作为市规划局的你,应当作出最佳的决策,选择那些道路应当被修建。


输入输出格式

输入格式:

第一行有两个整数n,m表示城市有n个交叉路口,m条道路。接下来m行是对每条道路的描述,u, v, c表示交叉路口u和v之间有道路相连,分值为c。(1≤n≤300,1≤c≤10000)

输出格式:

两个整数s, max,表示你选出了几条道路,分值最大的那条道路的分值是多少。

题解:一开始智商下线没看懂题目,后来发现就是一道最小生成树..

要求1是图联通;

要求2 最小边数,其实就是要n-1条边即树

要求3要边权和最小,最小生成树无疑

const
maxn=1000;
maxm=20000;
var
fa:array[0..maxn]of longint;
edge:array[0..maxm,1..3]of longint;
next,last:array[1..maxm]of longint;
n,sum,ans,i,m:longint;

procedure add(x,y,z:longint);
begin
inc(sum);
edge[sum,1]:=x;edge[sum,2]:=y;edge[sum,3]:=z;
next[sum]:=last[x];
last[x]:=sum;
end;

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

procedure union(x,y:longint);
var
u,v:longint;
begin
u:=find(x);v:=find(y);
if u<>v then fa[u]:=v;
end;

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

procedure init;
var
i,x,y,z:longint;
begin
readln(n,m);
for i:=1 to n do
fa[i]:=i;
for i:=1 to m do
begin
readln(x,y,z);
add(x,y,z);
add(y,x,z);
end;
qsort(1,sum);
end;

function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end;

procedure kruskal;
var
i:longint;
begin
for i:=1 to sum do
begin
if find(edge[i,1])<>find(edge[i,2]) then
begin
union(edge[i,1],edge[i,2]);
ans:=max(edge[i,3],ans);
end;
end;
end;

begin
init;
kruskal;
writeln(n-1,' ',ans);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: