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; }