Description
Zjr506很喜欢猫,某一天他突然心血来潮,想捕捉学校里活动的猫。
为了捕猫,Zjr506在校园中放置了N个木桩,当他见到有猫进入他的狩猎范围后,就会以迅雷不及掩耳的速度在一些木桩之间绕上藩篱以困住这些猫。
一段时间后,Zjr506在绕了M个藩篱后兴高采烈的离开了。作为正义的使者,Ztxz16不忍心看到这些猫受到折磨,于是决定拆除一些藩篱让所有的猫都逃出去。因为Zjr506的巧妙设计,藩篱不会在除木桩之外的地方相交。这些藩篱构成了一些封闭的区域,每一个区域中都有一只猫。
因为Zjr506制造这些藩篱也不容易,所以Ztxz16希望拆除的藩篱总长度尽量小,现在他希望你告诉他最小的总长度。
Input
第一行两个数 n,m ( 2<=n<=10000 , 1<=m<=50000 )
接下来 n 行 , 每行两个整数 xi,yi, 代表第 i 个木桩的坐标 ( − 10000 ≤ xi, yi ≤ 10000).
接下来 m 行,每行两个整数 pi,qi (1 ≤ pj, qj ≤ N) , 代表木桩 pi 与木桩 qi 之间有一个藩篱。
Output
输出一个实数代表答案,当答案与标准答案差的绝对值不超过0.001时认为它是正确的。
Sample Input
8 8
0 0
3 0
3 3
0 3
1 1
1 2
2 2
2 1
1 2
2 3
3 4
4 1
5 6
6 7
7 8
8 5
Sample Output
4.000000000
Data Constraint
对于20%的数据:
N , M <= 30
对于30%的数据:
N, M <= 300
对于100%的数据:
N <= 10000, M <= 50000
思路:
我们先换个思路来理解这道题目
YY一下一个封闭牛圈,木桩看成点,篱笆看成边,既然他是要封闭的,那么他肯定是一个环,对吧?
现在我们去掉任意一条边,他就不是一个环而是一棵树了
题目要保证一定保证整幅图没有环(有环里面就有猫),我们就不能让这个图出现环
那这道题就是一道裸的MST……
只不过和MST不同的是,这里要删掉的边最短,所以是求最大生成树而已
用kruskal搞最大生成树,判断环用并查集
如果当前边连接x和y,而x的祖先和y的祖先相同,那再连就会有环出现,当前边不选
比较简单,那就AC吧
代码:
var
x,y,father:array[0..10000]of longint;
a:array[0..50000]of
record
dis:extended;
x,y:longint;
end;
n,m,i,j,k,l,r:longint;
ans:extended;
procedure qsort(l,r:longint);
var
i,j:longint;
mid:extended;
begin
i:=l;
j:=r;
mid:=a[(l+r)shr 1].dis;
repeat
while a[i].dis>mid do inc(i);
while a[j].dis<mid do dec(j);
if i<=j then
begin
a[0]:=a[i];
a[i]:=a[j];
a[j]:=a[0];
inc(i);
dec(j);
end;
until i>j;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end;
function getfather(x:longint):longint;
begin
if father[x]=x then exit(x);
father[x]:=getfather(father[x]);
exit(father[x]);
end;
begin
readln(n,m);
for i:=1 to n do readln(x[i],y[i]);
for i:=1 to m do
begin
readln(l,r);
a[i].x:=l;
a[i].y:=r;
a[i].dis:=sqrt(sqr(x[l]-x[r])+sqr(y[l]-y[r]));
end;
qsort(1,m);
for i:=1 to n do father[i]:=i;
for i:=1 to m do
begin
j:=getfather(a[i].x);
k:=getfather(a[i].y);
if j<>k then father[j]:=k
else ans:=ans+a[i].dis;
end;
writeln(ans:0:9);
end.

1105

被折叠的 条评论
为什么被折叠?



