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 3405 world islands)