1 /*POJ 3164
2 一个通信网络被破坏了
3 给定每个点的坐标,和两两之间可修复的边和长度
4 现在选择部分修通,使从1点出发可到达所有点,并且代价最短
5
6 可看出是一个生成树的问题,做了UVA的那道,这道很简单了
7
8 PS:unidirection 是有向
9 undirecttion 才是无向
10 C++交才可以
11 */
12 #include<iostream>
13 #include<string.h>
14 #include<stdio.h>
15 #include<stdlib.h>
16 #include<cmath>
17 #include<algorithm>
18 #include<queue>
19 #include<stack>
20 #include<set>
21 #include<map>
22 #define maxn 100+5
23 #define maxe 20000+5
24 #define typec double
25 using namespace std;
26
27 const typec inf=99999999;
28 int nextint(){int x;scanf("%d",&x);return x;}
29 int nextdou(){double x;scanf("%lf",&x);return x;}
30 double X[maxn],Y[maxn];
31 double Dis(int i,int j){
32 double x1=X[i],x2=X[j],y1=Y[i],y2=Y[j];
33 return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
34 }
35 struct Edge{
36 int u,v;
37 typec c;//权值
38 }edge[maxe];
39
40 int vis[maxn],pre[maxn],id[maxn];
41 typec in[maxn];
42 typec zhuliu(int root,int nv,int ne){//最小树形图
43 int i,j,u,v;
44 typec ans=0;
45 while(1){
46 for(i=0;i<nv;i++)in[i]=inf;
47 for(i=0;i<ne;i++){
48 u=edge[i].u;
49 v=edge[i].v;
50 if(u!=v&&edge[i].c<in[v]){
51 pre[v]=u;
52 in[v]=edge[i].c;
53 }
54 }
55 in[root]=0;
56 for(i=0;i<nv;i++)if(fabs(in[i]-inf)<1e-6)return -1;
57 int cnt=0;
58 memset(id,-1,sizeof(id));
59 memset(vis,-1,sizeof(vis));
60 for(i=0;i<nv;i++){
61 v=i;
62 ans+=in[i];
63 while(vis[v]!=i&&id[v]==-1&&v!=root){
64 vis[v]=i;
65 v=pre[v];
66 }
67 if(v!=root&&id[v]==-1){
68 for(u=pre[v];u!=v;u=pre[u])id[u]=cnt;
69 id[v]=cnt++;
70 }
71 }
72 if(cnt==0)break;
73 for(i=0;i<nv;i++)if(id[i]==-1)id[i]=cnt++;
74 for(i=0;i<ne;i++){
75 v=edge[i].v;
76 edge[i].u=id[edge[i].u];
77 edge[i].v=id[edge[i].v];
78 if(edge[i].u!=edge[i].v)edge[i].c-=in[v];
79 }
80 nv=cnt;root=id[root];
81 }
82 return ans;
83 }
84 int n,m;
85 int cnt;
86 void built_tree(){
87 cnt=0;
88 for(int i=0;i<m;i++){
89 int u=nextint(),v=nextint();
90 u--,v--;
91 double dis=Dis(u,v);
92 // cout<<u<<","<<v<<" dis="<<dis<<endl;
93 edge[cnt].u=u;
94 edge[cnt].v=v;
95 edge[cnt++].c=dis;
96 // edge[cnt++]=(Edge){v,u,dis};
97 }
98 }
99 int main(){
100 // freopen("out.txt","w",stdout);
101 while(cin>>n>>m){
102 for (int i=0;i<n;i++){
103 X[i]=nextdou();
104 Y[i]=nextdou();
105 }
106 built_tree();
107 double ans=zhuliu(0,n,cnt);
108 if (ans<0) printf("poor snoopy\n");else printf("%.2lf\n",ans);
109 }
110 return 0;
111 }