hdu 1875

畅通工程再续

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 22628    Accepted Submission(s): 7222


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!
 

Author
8600
 




并查集  ::::

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


using namespace std;
int p[105];
int ran[105],x[105],y[105];
struct node
{
    int u,v;
    double s;
};


bool cmp(const node &lhs,const node &rhs)
{
    return lhs.s<rhs.s;
}
void make_set()
{
    int i;
    for(i=0;i<=105;i++)
        p[i]=i;
}
int find_set(int i)
{
    if(i!=p[i])
        p[i]=find_set(p[i]);
    return p[i];
}
int Union(int i,int j)
{
    i=find_set(i);
    j=find_set(j);
    if(i==j)
        return 0;
    if(ran[i]<ran[j])
        p[i]=j;
    else
    {
        p[j]=i;
        if(ran[i]==ran[j])
            ran[i]++;
    }
    return 1;
}
void init()
{
    make_set();
    memset(ran,0,sizeof(ran));
    memset(x,0,sizeof(x));
    memset(y,0,sizeof(y));
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int c;
        node map[6000];
        init();
        scanf("%d",&c);
        int i;
        for(i=0;i<c;i++)
            scanf("%d%d",&x[i],&y[i]);
        int j;
        int k=0;
        for(i=0;i<c;i++)
        {
            for(j=i+1;j<c;j++)
            {
                double t=sqrt((double)(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
                if(t<10.0||t>1000.0)
                    continue;
                map[k].u=i;
                map[k].v=j;
                map[k].s=t;
                k++;
            }
        }
        sort(map,map+k,cmp);
        double sum=0;
        for(i=0;i<k;i++)
        {
            if(Union(map[i].u,map[i].v))
                sum+=map[i].s;
        }
        int count=0;
        for(i=0;i<c;i++)
            if(p[i]==i)
                count++;
        if(count==1)
            printf("%.1f\n",sum*100);
        else
            printf("oh!\n");
    }
    return 0;
}




最小 生成树!!!

  1. #include <iostream>  
  2. using namespace std;  
  3. #include <cmath>  
  4. const double INF=0x3f3f3f3f*1.0;  
  5. struct node  
  6. {  
  7.     int x;  
  8.     int y;  
  9. };  
  10.   
  11. double d[105][105];  
  12. int c;//岛屿个数  
  13. void prim()  
  14. {  
  15.     double sum=0,lowcast[105]={0};  
  16.     int count=1;  
  17.     for(int i=0;i<c;i++)  
  18.     {  
  19.         lowcast[i] = d[0][i];  
  20.     }  
  21.     for(int i=0;i<c-1;i++)  
  22.     {  
  23.         double min = INF;//INF是自定义常量,表无穷大  
  24.         int k = 105;  
  25.         for(int j=0;j<c;j++)  
  26.             if(min>lowcast[j]&&lowcast[j])  
  27.             {  
  28.                 min = lowcast[j];  
  29.                 k = j;  
  30.             }  
  31.         if(k!=105)  
  32.         {  
  33.             sum+=lowcast[k];  
  34.             lowcast[k]=0;  
  35.             count++;  
  36.         }  
  37.         for(int j=0;j<c;j++)  
  38.             if(d[j][k]<lowcast[j])  
  39.             {  
  40.                 lowcast[j] = d[j][k];  
  41.             }  
  42.     }  
  43.     if(count==c)  
  44.         printf("%.1lf\n",sum*100);  
  45.     else  
  46.         printf("oh!\n");  
  47. }  
  48. int main()  
  49. {  
  50.   
  51.     int t;  
  52.     cin>>t;  
  53.     while(t--)  
  54.     {  
  55.         node n[105];  
  56.         cin>>c;  
  57.         for(int i=0;i<c;i++)  
  58.             cin>>n[i].x>>n[i].y;  
  59.         for(int i=0;i<c;i++)  
  60.             for(int j=0;j<c;j++)  
  61.             {  
  62.                 if(i==j)  
  63.                 {         
  64.                     d[i][j]=0;  
  65.                     continue;  
  66.                 }  
  67.   
  68.                 int x1=n[i].x, x2=n[j].x;  
  69.                 int y1=n[i].y, y2=n[j].y;  
  70.                 double dist=sqrt(1.0*(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));  
  71.                 if(dist<10.0||dist>1000.0)  
  72.                     d[j][i]=d[i][j]=INF;  
  73.                 else  
  74.                     d[j][i]=d[i][j]=dist;  
  75.             }  
  76.             prim();  
  77.     }  
  78.     return 0;  
  79. }  

你可能感兴趣的:(hdu 1875)