1. 程式人生 > >HDU - 1875_暢通工程再續

HDU - 1875_暢通工程再續

暢通工程再續

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Problem Description

相信大家都聽說一個“百島湖”的地方吧,百島湖的居民生活在不同的小島中,當他們想去其他的小島時都要通過劃小船來實現。現在政府決定大力發展百島湖,發展首先要解決的問題當然是交通問題,政府決定實現百島湖的全暢通!經過考察小組RPRush對百島湖的情況充分了解後,決定在符合條件的小島間建上橋,所謂符合條件,就是2個小島之間的距離不能小於10米,也不能大於1000米。當然,為了節省資金,只要求實現任意2個小島之間有路通即可。其中橋的價格為 100元/米。

Input

輸入包括多組資料。輸入首先包括一個整數T(T <= 200),代表有T組資料。
每組資料首先是一個整數C(C <= 100),代表小島的個數,接下來是C組座標,代表每個小島的座標,這些座標都是 0 <= x, y <= 1000的整數。

Output

每組輸入資料輸出一行,代表建橋的最小花費,結果保留一位小數。如果無法實現工程以達到全部暢通,輸出”oh!”.

Sample Input

2
2
10 10
20 20
3
1 1
2 2
1000 1000

Sample Output

1414.2
oh!

題解:用kruskal求最小生成樹,注意判斷邊權,然後在並茶几那裡出bug了,wa了好幾發。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>

using namespace std;

const int maxn = 1050;

struct point
{
    int x,y;
}p[105];

struct edge
{
    int v,u;
    double w;
}s[10050];

int num,head[maxn],n;

void add(int u,int v,double w)
{
   // cout<<u<<' '<<v<<' '<<w<<endl;
    s[num].u = u;
    s[num].v = v;
    s[num].w = w;
    num++;
}

double dis(point a,point b)
{
    return sqrt(1.0*(a.x-b.x)*(a.x-b.x)+1.0*(a.y-b.y)*(a.y-b.y));
}

int Find(int x)
{
    return x==head[x]?x:head[x] = Find(head[x]);
}

double kruskal()
{
    double w,sum = 0;
    int i,v,u,ans = 0;
    for(i=0;i<num;i++)
    {
        u = s[i].u;
        v = s[i].v;
        w = s[i].w;
        //cout<<"WTF"<<endl;
        int a = Find(u);
        int b = Find(v);
        if(a!=b&&w>=10&&w<=1000)
        {
            //cout<<w<<endl;
            head[b] = a;
            sum += w;
        }
    }
    for(i=0;i<n;i++)
    {
        if(head[i]==i)
            ans ++;
    }
    if(ans==1)
        return sum;
    return -1;
}

void init(int n)
{
    for(int i=0;i<n;i++)
        head[i] = i;
}

bool cmp(edge a,edge b)
{
    return a.w<b.w;
}

int main()
{
    int i,t,j;
    scanf("%d",&t);
    while(t--)
    {
        num = 0;
        scanf("%d",&n);
        init(n);
        for(i=0;i<n;i++)
        {
            scanf("%d%d",&p[i].x,&p[i].y);
            for(j=0;j<i;j++)
            {
                add(i,j,dis(p[i],p[j]));
            }
        }
        if(n==1||n==0)
        {
            printf("0\n");
            continue;
        }
        sort(s,s+num,cmp);
        double a = kruskal();
        if(a==-1)
            printf("oh!\n");
        else
            printf("%.1f\n",a*100);
    }
    return 0;
}