朱刘算法模板题
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#define eps 1e-8
#define INF 0x7fffffff
using namespace std;
struct point
{
double x;
double y;
};
struct edge
{
int u;
int v;
double w;
};
double dis(point a, point b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
point p[120];
edge e[12000];
int n,m;
int color[120],pr[120],vis[120];
double prv[120];
double pigleft(int root)
{
int u,v,i;
int cnt;
double ans=0.0;
while (true)
{
for (i=1; i<=n; i++)
prv[i]=INF;
for (i=0; i<m; i++)
{
u=e[i].u;
v=e[i].v;
if (e[i].w < prv[v] && u != v)
{
pr[v]=u;
prv[v]=e[i].w;
}
}
for (i=1; i<=n; i++)
{
if (i == root)
continue;
if (prv[i] == INF)
return -1;
}
cnt=1;
memset(color,-1,sizeof(color));
memset(vis,-1,sizeof(vis));
prv[root]=0;
for (i=1; i<=n; i++)
{
ans+=prv[i];
v=i;
while (vis[v] != i && color[v] == -1 && v != root)
{
vis[v]=i;
v=pr[v];
}
if (v != root && color[v] == -1)
{
for (u=pr[v]; u != v; u=pr[u])
color[u]=cnt;
color[u]=cnt;
cnt++;
}
}
if (cnt == 1)
break;
for (i=1; i<=n; i++)
{
if (color[i] == -1)
{
color[i]=cnt;
cnt++;
}
}
for (i=0; i<m; i++)
{
u=e[i].u;
v=e[i].v;
e[i].u=color[u];
e[i].v=color[v];
if (color[u] != color[v])
{
e[i].w-=prv[v];
}
}
n=cnt-1;
root=color[root];
}
return ans;
}
int main()
{
int i;
double ans;
while (scanf("%d%d",&n,&m) != EOF)
{
for (i=1; i<=n; i++)
{
scanf("%lf%lf",&p[i].x,&p[i].y);
}
for (i=0; i<m; i++)
{
scanf("%d%d",&e[i].u,&e[i].v);
if (e[i].u == e[i].v)
e[i].w=INF;
else
e[i].w=dis(p[e[i].u],p[e[i].v]);
}
ans=pigleft(1);
if (fabs(ans+1) < eps)
printf("poor snoopy\n");
else
printf("%.2f\n",ans);
}
}