#会津大学オンラインジャッジ問0342 Road Planningに合格したコード、Rubyで通ったのは私だけ。
def f3(a,b)
dx=(a[0]-b[0]).abs
dy=(a[1]-b[1]).abs
return Math.sqrt(dx**2+dy**2)
end
def g(as,e1,e2)
dx2=e2[0]-e1[0]
dy2=e2[1]-e1[1]
as.each{|e3|
next if e1==e3 || e2==e3
dx3=e3[0]-e1[0]
dy3=e3[1]-e1[1]
g1=dx2*dy3-dx3*dy2
return false if g1<0.0
}
return true
end
def f(as,gs)
p1=as.min
logp=[p1]
gs2={}
hs={}
hs[p1]=0
hit=true
l1=0.0
while hit do
hit=false
as.each{|e|
next if hs.member?(e)
next if g(as,p1,e)==false
logp<<e
hs[e]=0
hit=true
l1+=f3(p1,e)
p1=e
break
}
end
l1+=f3(logp[0],logp.last)
logp.each{|e|
if gs.member?(e) then
gs[e].each{|e2|
next if hs.member?(e2)
t1=f3(e,e2)
gs2[t1]=[] if gs2.member?(t1)==false
gs2[t1]<<e2
}
end
}
return [gs2,hs,l1]
end
n,m=gets.split(" ").map{|e| e.to_i}
as=[]
n.times{
as<<gets.split(" ").map{|e| e.to_f}
}
gs={}
m.times{
a,b=gets.split(" ").map{|e| as[e.to_i-1]}
gs[a]=[] if gs.member?(a)==false
gs[b]=[] if gs.member?(b)==false
gs[a]<<b
gs[b]<<a
}
gs2,hs2,l2= f(as,gs)
while hs2.size<n do
ts1=gs2.min
t2=ts1[0]
es=ts1[1]
if es.size==0 then
gs2.delete(t2)
else
hit=false
while gs2[t2].size>0 do
e2=gs2[t2].shift
next if hs2.member?(e2)
hit=true
hs2[e2]=0
l2+=t2
if hs2.size==n then
break
end
gs[e2].each{|e3|
next if hs2.member?(e3)
t2=f3(e2,e3)
gs2[t2]=[] if gs2.member?(t2)==false
gs2[t2]<<e3
}
break if hit==true
end
end
end
puts sprintf("%.4f",l2)
I+S8mua0peWkp+WtpuOCquODs+ODqeOCpOODs+OCuOODo+ODg+OCuOWVjzAzNDLjgIBSb2FkIFBsYW5uaW5n44Gr5ZCI5qC844GX44Gf44Kz44O844OJ44CBUnVieeOBp+mAmuOBo+OBn+OBruOBr+engeOBoOOBkeOAggpkZWYgZjMoYSxiKQoJZHg9KGFbMF0tYlswXSkuYWJzCglkeT0oYVsxXS1iWzFdKS5hYnMKCXJldHVybiBNYXRoLnNxcnQoZHgqKjIrZHkqKjIpCmVuZAoKZGVmIGcoYXMsZTEsZTIpCglkeDI9ZTJbMF0tZTFbMF0KCWR5Mj1lMlsxXS1lMVsxXQoJYXMuZWFjaHt8ZTN8CgkJbmV4dCBpZiBlMT09ZTMgfHwgZTI9PWUzCgkJZHgzPWUzWzBdLWUxWzBdCgkJZHkzPWUzWzFdLWUxWzFdCgkJZzE9ZHgyKmR5My1keDMqZHkyCgkJcmV0dXJuIGZhbHNlIGlmIGcxPDAuMAoJfQoJcmV0dXJuIHRydWUKZW5kCmRlZiBmKGFzLGdzKQoJcDE9YXMubWluCglsb2dwPVtwMV0KCWdzMj17fQoJaHM9e30KCWhzW3AxXT0wCgloaXQ9dHJ1ZQoJbDE9MC4wCgl3aGlsZSBoaXQgZG8KCQloaXQ9ZmFsc2UKCQlhcy5lYWNoe3xlfAoJCQluZXh0IGlmIGhzLm1lbWJlcj8oZSkKCQkJbmV4dCBpZiBnKGFzLHAxLGUpPT1mYWxzZQoJCQlsb2dwPDxlCgkJCWhzW2VdPTAKCQkJaGl0PXRydWUKCQkJbDErPWYzKHAxLGUpCgkJCXAxPWUKCQkJYnJlYWsKCQl9CgllbmQKCWwxKz1mMyhsb2dwWzBdLGxvZ3AubGFzdCkKCWxvZ3AuZWFjaHt8ZXwKCQlpZiBncy5tZW1iZXI/KGUpIHRoZW4KCQkJZ3NbZV0uZWFjaHt8ZTJ8CgkJCQluZXh0IGlmIGhzLm1lbWJlcj8oZTIpCgkJCQl0MT1mMyhlLGUyKQoJCQkJZ3MyW3QxXT1bXSBpZiBnczIubWVtYmVyPyh0MSk9PWZhbHNlCgkJCQlnczJbdDFdPDxlMgoJCQl9CgkJZW5kCgl9CgkKCXJldHVybiBbZ3MyLGhzLGwxXQplbmQKCm4sbT1nZXRzLnNwbGl0KCIgIikubWFwe3xlfCBlLnRvX2l9CmFzPVtdCm4udGltZXN7Cglhczw8Z2V0cy5zcGxpdCgiICIpLm1hcHt8ZXwgZS50b19mfQp9Cgpncz17fQptLnRpbWVzewoJYSxiPWdldHMuc3BsaXQoIiAiKS5tYXB7fGV8IGFzW2UudG9faS0xXX0KCWdzW2FdPVtdIGlmIGdzLm1lbWJlcj8oYSk9PWZhbHNlCglnc1tiXT1bXSBpZiBncy5tZW1iZXI/KGIpPT1mYWxzZQoJZ3NbYV08PGIKCWdzW2JdPDxhCn0KZ3MyLGhzMixsMj0gZihhcyxncykKCndoaWxlIGhzMi5zaXplPG4gZG8KCXRzMT1nczIubWluCgl0Mj10czFbMF0KCWVzPXRzMVsxXQoJaWYgZXMuc2l6ZT09MCB0aGVuCgkJZ3MyLmRlbGV0ZSh0MikKCWVsc2UKCQloaXQ9ZmFsc2UKCQl3aGlsZSBnczJbdDJdLnNpemU+MCBkbwoJCQllMj1nczJbdDJdLnNoaWZ0CgkJCW5leHQgaWYgaHMyLm1lbWJlcj8oZTIpCgkJCWhpdD10cnVlCgkJCWhzMltlMl09MAoJCQlsMis9dDIKCQkJaWYgaHMyLnNpemU9PW4gdGhlbgoJCQkJYnJlYWsKCQkJZW5kCgkJCWdzW2UyXS5lYWNoe3xlM3wKCQkJCW5leHQgaWYgaHMyLm1lbWJlcj8oZTMpCgkJCQl0Mj1mMyhlMixlMykKCQkJCWdzMlt0Ml09W10gaWYgZ3MyLm1lbWJlcj8odDIpPT1mYWxzZQoJCQkJZ3MyW3QyXTw8ZTMKCQkJfQoJCQlicmVhayBpZiBoaXQ9PXRydWUKCQllbmQKCWVuZAplbmQKcHV0cyBzcHJpbnRmKCIlLjRmIixsMik=