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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
| const int N = 110, M = 10010, INF=1e8; int n,m,k; pdd q[N]; bool g[N][N]; double d[N][N],bd[N][N]; int pre[N],bkppre[N]; int dfn[N],low[N],timestamp,stk[N],top; int id[N],scc_cnt=0; bool st[N],ins[N];
void dfs(int u){ st[u]=true; rep(i,1,n) if(g[u][i]&&!st[i]) dfs(i); }
bool check_con(){ memset(st,0,sizeof st); dfs(1); rep(i,1,n) if(!st[i]) return false; return true; }
double get_dist(int a,int b){ double dx = q[a].x-q[b].x; double dy = q[a].y-q[b].y; return sqrt(dx*dx+dy*dy); }
void tarjan(int u){ dfn[u]=low[u]=++timestamp; stk[++top]=u,ins[u]=true; int j=pre[u]; if(!dfn[j]){ tarjan(j); low[u]=min(low[u],low[j]); } else if(ins[j]) low[u]=min(low[u],dfn[j]); if(low[u]==dfn[u]){ int y; scc_cnt ++; do{ y=stk[top --]; ins[y]=false; id[y]=scc_cnt; }while(y!=u); } }
double zhuliu(){ double ans= 0; for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) if(g[i][j]) d[i][j] = get_dist(i,j); else d[i][j] = INF; while(true) { for(int i=1;i<=n;++i){ pre[i]=i; for(int j=1;j<=n;++j){ if(d[pre[i]][i] > d[j][i]) pre[i]=j; } } memset(dfn,0,sizeof dfn); timestamp=scc_cnt=0; for(int i=1;i<=n;++i) if(!dfn[i]) tarjan(i); if(scc_cnt == n) { for(int i=2;i<=n;++i) ans += d[pre[i]][i]; break; } for(int i=2;i<=n;++i) if(id[pre[i]]==id[i]) ans += d[pre[i]][i]; for(int i=1;i<=scc_cnt;++i) for(int j=1;j<=scc_cnt;j++) bd[i][j] = INF; for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) if(d[i][j] < INF && id[i] != id[j]){ int a=id[i],b=id[j]; if(id[pre[j]] == id[j]) bd[a][b]=min(bd[a][b],d[i][j]-d[pre[j]][j]); else bd[a][b] = min(bd[a][b], d[i][j]); } n = scc_cnt; memcpy(d,bd,sizeof d); } return ans; }
void solve(){ rep(i,1,n) scanf("%lf%lf",&q[i].x,&q[i].y); memset(g,0,sizeof g); while(m--){ int a=read(),b=read(); if(a!=b&&b!=1) g[a][b]=true; } if(!check_con()) puts("poor snoopy"); else printf("%.2lf\n",zhuliu()); }
int main(){ while(~scanf("%d%d",&n,&m)){ solve(); } return 0; }
|