http://poj.org/problem?id=3164
比着别人的代码写的 有些地方还是不理解 但是不能老在这上面耽误 先放一下 以后遇到再慢慢研究
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<map>
#include<queue>
#include<cmath>
#define LL long long
using namespace std;
const int N=105;
const double M=pow(2.0,32);
struct point
{
double x,y;
}mem[N];
struct ss
{
int i,j;
double d;
}side[N*N];
bool lin[N][N];
double in[N];
int vi[N];
int pre[N];
int f[N];
int n,m;
double Fdist(int i,int j)
{
return sqrt((mem[i].x-mem[j].x)*(mem[i].x-mem[j].x)+
(mem[i].y-mem[j].y)*(mem[i].y-mem[j].y));
}
double min_utree()
{
double ans=0.0;
int v=n;
int root=1;
while(1)
{
for(int i=1;i<=v;++i)
in[i]=M;
for(int l=0;l<m;++l)
{
int x=side[l].i;
int y=side[l].j;
if(x==y)
continue;
if(side[l].d<in[y])
{
pre[y]=x;
in[y]=side[l].d;
}
}
memset(f,-1,sizeof(f));
memset(vi,-1,sizeof(vi));
int num=0;
in[root]=0;
for(int i=1;i<=v;++i)
{
ans=ans+in[i];
int l=i;
while(l!=root&&vi[l]!=i&&f[l]==-1)
{
vi[l]=i;
l=pre[l];
}
if(l!=root&&f[l]==-1)
{
++num;
int k=pre[l];
while(k!=l)
{
f[k]=num;
k=pre[k];
}
f[l]=num;
}
}
if(num==0)
break;
for(int i=1;i<=v;++i)
if(f[i]==-1)
f[i]=(++num);
for(int l=0;l<m;++l)
{
int x=side[l].i;
int y=side[l].j;
side[l].i=f[x];
side[l].j=f[y];
if(f[x]!=f[y])
{
side[l].d=(side[l].d-in[y]);
}
}
root=f[root];
v=num;
}
return ans;
}
void dfs(int x)
{
vi[x]=1;
for(int i=1;i<=n;++i)
{
if(vi[i]==0&&lin[x][i])
dfs(i);
}
}
int main()
{
//freopen("data.txt","r",stdin);
while(scanf("%d %d",&n,&m)!=EOF)
{
for(int i=1;i<=n;++i)
scanf("%lf %lf",&mem[i].x,&mem[i].y);
memset(lin,false,sizeof(lin));
for(int l=0;l<m;++l)
{
scanf("%d %d",&side[l].i,&side[l].j);
side[l].d=Fdist(side[l].i,side[l].j);
if(side[l].i==side[l].j)
side[l].d=M;
lin[side[l].i][side[l].j]=true;
}
memset(vi,0,sizeof(vi));
dfs(1);
int l;
for(l=1;l<=n;++l)
if(vi[l]==0)
break;
if(l<=n)
{
printf("poor snoopy\n");
continue;
}
double ans=min_utree();
printf("%.2f\n",ans);
}
return 0;
}