题目: | 联络员 | |
来源: | Tyvj 1307 | |
题目大意: | N个点M条边,每条边都有一个权值,有些边是必选的,求最小生成树 | |
数据范围: | n<=2000 m<=10000 | |
样例: | 5 6 1 1 2 1 1 2 3 1 1 3 4 1 1 4 1 1 2 2 5 10 2 2 5 5 | 9 |
做题思路: | 哦,必连边,先把他们的权值加上然后再把它改成0做kruskal最小生成树就哦了 | |
知识点: | Kruskal 必连边最小生成树 |
type
act=record
x,y,d:longint;
end;
var
f:array[0..2010]of longint;
a:array[0..10010]of act;
p,n,m,i,j,ans:longint;
procedure qsort(l,r:longint);
var
i,j,k:longint;
t:act;
begin
i:=l;j:=r;
k:=a[(l+r)div 2].d;
repeat
while a[i].d<k do inc(i);
while a[j].d>k do dec(j);
ifi<=j then
begin
t:=a[i];a[i]:=a[j];a[j]:=t;
inc(i);dec(j);
end;
until i>j;
ifi<r then qsort(i,r);
ifj>l then qsort(l,j);
end;
function getf(x:longint):longint;
begin
iff[x]=x then exit(x)
else getf:=getf(f[x]);
end;
procedure union(x,y:longint);
begin
f[getf(x)]:=getf(y);
end;
procedure kruskal;
var
tot,i,j:longint;
begin
i:=1;
tot:=0;
while tot<n do
begin
ifgetf(a[i].x)<>getf(a[i].y) then
begin
union(a[i].x,a[i].y);
inc(ans,a[i].d);
inc(tot);
end;
inc(i);
end;
end;
begin
readln(n,m);
fori:=1 to n do
f[i]:=i;
ans:=0;
fori:=1 to m do
begin
readln(p,a[i].x,a[i].y,a[i].d);{<处理必连边>}
ifp=1 then
begin
inc(ans,a[i].d);
a[i].d:=0;
end;
end;
qsort(1,m);
kruskal;
writeln(ans);
end.
题目来源:
http://www.tyvj.cn:8080/Problem_Show.asp?id=1307