hdu 3405 world islands

求删点后最小的生成树,n<50.。。。数据好弱,直接暴力枚举就行。。。删点的时候直接g[i][j]=INF就行了。

 

#include<iostream>

#include<algorithm>

#include<fstream>

#include<string>

#include<vector>

#include<stack>

#include<queue>

#include<cstdio>

#include<cstring>

#include<cstdlib>

#include<cmath>

#include<map>

#include<set>

#define FF(i, a, b) for(i=a; i<b; i++)

#define FD(i, a, b) for(i=a; i>b; i--)

#define CLR(a, b) memset(a, b, sizeof(a))

#define LL long long

#define CPY(a, b) memcpy(a, b, sizeof(b))

using namespace std;

ofstream fout ("output.txt");

ifstream fin ("input.txt");



const int maxn = 100;

const double INF = 222222;

int T, n;

double g[maxn][maxn], low[maxn], x[maxn], y[maxn], tmp[maxn][maxn];

bool vis[maxn];



double prim(int start)

{

    double  min, res=0;

    int i, j, pos;

    CLR(vis, 0);

    vis[start] = 1; pos = start;

    FF(i, 1, n+1)   if(i!=pos) low[i] = g[pos][i];

    FF(i, 1, n)

    {

        min = INF;

        FF(j, 1, n+1)

            if(vis[j] == 0 && min > low[j])

                min = low[j], pos = j;

        res += min;

        vis[pos] = 1;

        FF(j, 1, n+1)

            if(vis[j] == 0 && low[j] > g[pos][j])

                low[j] = g[pos][j];

    }

    return res;

}



int main()

{

    scanf("%d", &T);

    while(T--)

    {

        int i, j;

        scanf("%d", &n);

        FF(i, 1, n+1)  scanf("%lf%lf", &x[i], &y[i]);

        FF(i, 1, n+1)

            FF(j, 1, n+1)

                g[i][j] = sqrt((x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]));

        double ans = INF*INF;

        FF(i, 1, n+1)

        {

            CPY(tmp, g);

            FF(j, 1, n+1)

            {

                g[i][j] = g[j][i] = INF;

            }

            ans = min(ans, prim(1));

            CPY(g, tmp);

        }

        printf("%.2lf\n", n < 3 ? 0 : ans-INF);

    }

    return 0;

}


 

 

你可能感兴趣的:(HDU)