Description
城市C是一个非常繁忙的大都市,城市中的道路十分的拥挤,于是市长决定对其中的道路进行改造。城市C的道
路是这样分布的:城市中有n个交叉路口,有些交叉路口之间有道路相连,两个交叉路口之间最多有一条道路相连
接。这些道路是双向的,且把所有的交叉路口直接或间接的连接起来了。每条道路都有一个分值,分值越小表示这
个道路越繁忙,越需要进行改造。但是市政府的资金有限,市长希望进行改造的道路越少越好,于是他提出下面的
要求: 1. 改造的那些道路能够把所有的交叉路口直接或间接的连通起来。 2. 在满足要求1的情况下,改造的
道路尽量少。 3. 在满足要求1、2的情况下,改造的那些道路中分值最大的道路分值尽量小。任务:作为市规划
局的你,应当作出最佳的决策,选择那些道路应当被修建。
Input
第一行有两个整数n,m表示城市有n个交叉路口,m条道路。接下来m行是对每条道路的描述,u, v, c表示交叉
路口u和v之间有道路相连,分值为c。(1≤n≤300,1≤c≤10000)
Output
两个整数s, max,表示你选出了几条道路,分值最大的那条道路的分值是多少。
分析
裸题,kruskal+并查集优化,算是补上了
code
/**************************************************************
Problem: 1083
User: jpwang
Language: C++
Result: Accepted
Time:30 ms
Memory:940 kb
****************************************************************/
#include
#include
using namespace std;
struct edge
{
int x,y,w;
};
int ans;
edge e[10001];
int f[301];
bool cmp(edge x,edge y)
{
return x.wint find(int x)
{
int t=f[x];
if (t==0)
return x;
f[x]=find(t);
return f[x];
}
void merge(int x,int y)
{
if (find(x)!=find(y))
f[x]=y;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
sort(e+1,e+m+1,cmp);
int k=0,ans=0;
for (int i=1;iif (kint a=find(e[i].x);
int b=find(e[i].y);
if (a!=b)
{
ans=e[i].w>ans?e[i].w:ans;
merge(a,b);
k++;
}
}
printf("%d %d\n",k,ans);
return 0;
}
type
edge=record
x,y,w:longint;
end;
var
a,b,m,n,i,k:longint;
f,v:array[1..1000]of longint;
e:array[1..10000]of edge;
min,ans:longint;
procedure qsort(l,r:longint);
var
x,y,key:longint;
temp:edge;
begin
if l>=r then exit;
x:=l;
y:=r;
key:=e[l+random(r-l+1)].w;
repeat
while (e[x].wdo inc(x);
while (e[y].w>key) do dec(y);
if x<=y then
begin
temp:=e[x];
e[x]:=e[y];
e[y]:=temp;
inc(x);
dec(y);
end;
until x>y;
qsort(l,y);
qsort(x,r);
end;
function find(x:longint):longint;
var
y,w,root:longint;
begin
y:=x;
while f[y]<>0 do y:=f[y];
root:=y;
y:=x;
while f[y]<>0 do
begin
w:=f[y];
f[y]:=root;
y:=w;
end;
find:=root;
end;
procedure union(x,y:longint);
begin
if find(x)<>find(y) then
f[x]:=y;
end;
procedure init;
var
i:Longint;
begin
readln(n,m);
for i:=1 to m do
with e[i] do
readln(x,y,w);
fillchar(f,sizeof(f),0);
ans:=0;
end;
begin
init;
qsort(1,m);
k:=0;
for i:=1 to m-1 do
if k=n then break
else
begin
a:=find(e[i].x);
b:=find(e[i].y);
if a<>b then
begin
if e[i].w>ans then ans:=e[i].w;
union(a,b);
inc(k);
end;
end;
writeln(k,' ',ans);
end.