题目描述
城市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.