1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <cmath> #define db long double #define ll long long using namespace std; template <class T> inline void rd(T &x) { x=0; char c=getchar(); int f=1; while(!isdigit(c)){if(c=='-')f=-1; c=getchar();} while(isdigit(c)) x=x*10-'0'+c,c=getchar(); x*=f; } const int N=110,M=10010; struct Point { db x,y; Point(db x=0,db y=0): x(x),y(y) {} friend Point operator -(Point A,Point B) { return Point(A.x-B.x,A.y-B.y); } db dis() { return sqrt(x*x+y*y); } }p[N]; struct ed{int u,v; db w;}E[M]; int vis[N],pre[N],bel[N],n,m,rt; db cost[N]; void DMST(int n,int m,int rt) { db ans=0; while(true) { for(int i=1;i<=n;++i) vis[i]=0,pre[i]=-1,cost[i]=1e100,bel[i]=-1; for(int i=1;i<=m;++i) { if(E[i].v==rt) continue; if(E[i].u==E[i].v) continue; if(cost[E[i].v]>E[i].w) cost[E[i].v]=E[i].w,pre[E[i].v]=E[i].u; } for(int i=1;i<=n;++i) { if(i==rt) continue; if(pre[i]==-1) { printf("poor snoopy\n"); return; } ans+=cost[i]; }
int cnt=0; for(int i=1,v,x;i<=n;++i) if(i!=rt&&!vis[i]) { vis[i]=i; for(v=pre[i];!vis[v]&&v!=rt;v=pre[v]) vis[v]=i; if(vis[v]!=i) continue; ++cnt; bel[v]=cnt; for(x=pre[v];x!=v;x=pre[x]) bel[x]=cnt; } if(cnt==0) break; for(int i=1;i<=n;++i) if(bel[i]==-1) bel[i]=++cnt; for(int i=1;i<=m;++i) { while(i<=m&&bel[E[i].u]==bel[E[i].v]) { swap(E[i],E[m]),m--; } if(i>m) break; E[i].w-=cost[E[i].v]; E[i].u=bel[E[i].u],E[i].v=bel[E[i].v]; } n=cnt,rt=bel[rt]; } printf("%.2Lf\n",ans); } int main() { while(~scanf("%d%d",&n,&m)) { rt=1; for(int i=1;i<=n;++i) scanf("%Lf%Lf",&p[i].x,&p[i].y); for(int i=1;i<=m;++i) { scanf("%d%d",&E[i].u,&E[i].v); E[i].w=(p[E[i].u]-p[E[i].v]).dis(); } DMST(n,m,rt); } return 0; }
|