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

  

posted on 2012-08-14 09:33  夜->  阅读(144)  评论(0编辑  收藏  举报