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 ");else printf("%.2lf ",ans); 109 } 110 return 0; 111 }