POJ3164-最小树形图

//A是A了,有蛋也疼的代码
#include <cstdio>
#include <vector>
#include <cmath>
#include <cstring>
#include <iostream>
using namespace std;

const int NN=110;
const double INF=1e20;

int n,m;
int pre[NN];
double x[NN],y[NN],d[NN][NN];
bool vis[NN],circle[NN];

void dfs(int u)
{
    vis[u]=true;
    for (int i=1; i<=n; i++)
    {
        if (d[u][i]!=INF && !vis[i]) dfs(i);
    }
}

void zhuliu()
{
    int i,j,k;
    double cost=0;
    memset(circle,0,sizeof(circle));

    while(true)
    {
        for(i=2; i<=n; i++)
        {
            if(circle[i]) continue;
            pre[i]=i;
            d[i][i]=INF;
            for(j=1; j<=n; j++)
            {
                if(circle[j]) continue;
                if(d[j][i]<d[pre[i]][i])
                    pre[i]=j;
            }
        }
        for(i=2; i<=n; i++)
        {
            if(circle[i]) continue;
            j=i;
            memset(vis,false,sizeof(vis));
            while(!vis[j] && j!=1)
            {
                vis[j]=true;
                j=pre[j];
            }
            if(j==1) continue;
            i=j;
            cost+=d[pre[i]][i];
            for(j=pre[i]; j!=i; j=pre[j])
            {
                cost+=d[pre[j]][j];
                circle[j]=true;
            }
            for(j=1; j<=n; j++)
            {
                if(circle[j]) continue;
                if(d[j][i]!=INF)
                    d[j][i]-=d[pre[i]][i];
            }
            for(j=pre[i]; j!=i; j=pre[j])
                for(k=1; k<=n; k++)
                {
                    if(circle[k]) continue;
                    d[i][k]=min(d[i][k],d[j][k]);
                    if(d[k][j]!=INF)
                        d[k][i]=min(d[k][i],d[k][j]-d[pre[j]][j]);
                }
            break;
        }
        if(i>n)
        {
            for(j=2; j<=n; j++)
            {
                if(circle[j]) continue;
                cost+=d[pre[j]][j];
            }
            break;
        }
    }
    printf("%.2lf\n",cost);
}

int main()
{
    while (scanf("%d%d",&n,&m)!=EOF)
    {
        for (int i=1; i<=n; i++) scanf("%lf%lf",&x[i],&y[i]);
        for (int i=1; i<=n; i++)
            for (int j=1; j<=n; j++)
                d[i][j]=INF;

        int u,v;
        for (int i=1; i<=m; i++)
        {
            scanf("%d%d",&u,&v);
            if (u==v) continue;
            d[u][v]=sqrt((x[u]-x[v])*(x[u]-x[v])+(y[u]-y[v])*(y[u]-y[v]));
            //printf("%d %d: %.3f\n",u,v,d[u][v]);
        }

        memset(vis,0,sizeof(vis));
        dfs(1);
        bool flag=true;
        for (int i=1; i<=n && flag; i++) if (!vis[i]) flag=false;
        if (!flag)
        {
            printf("poor snoopy\n");
            continue;
        }

        zhuliu();
    }
    return 0;
}

你可能感兴趣的:(POJ3164-最小树形图)