• HDU-1875 畅通工程再续(最小生成树+判断是否存在)


    http://acm.hdu.edu.cn/showproblem.php?pid=1875

    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!
      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <iostream>
      4 #include <string>
      5 #include <math.h>
      6 #include <algorithm>
      7 #include <vector>
      8 #include <stack>
      9 #include <queue>
     10 #include <set>
     11 #include <map>
     12 #include <sstream>
     13 const int INF=0x3f3f3f3f;
     14 typedef long long LL;
     15 const int mod=1e9+7;
     16 //const double PI=acos(-1);
     17 #define Bug cout<<"---------------------"<<endl
     18 const int maxn=1e5+10;
     19 using namespace std;
     20 
     21 struct edge_node
     22 {
     23     int to;
     24     double val;
     25     int next;
     26 }Edge[maxn];
     27 int Head[110];
     28 int tot;
     29 double MST;//存放最小生成树权值和 
     30 
     31 struct node
     32 {
     33     int x;
     34     int y;
     35 }PT[110];//点信息 
     36  
     37 void Add_Edge(int u,int v,double w)
     38 {
     39     Edge[tot].to=v;
     40     Edge[tot].val=w;
     41     Edge[tot].next=Head[u];
     42     Head[u]=tot++;
     43 }
     44 
     45 double lowval[110];
     46 int pre[110];//记录每个点的双亲是谁
     47 
     48 double Prim(int n,int st)//n为顶点的个数,st为最小生成树的开始顶点
     49 {
     50     double sum=0;
     51     fill(lowval,lowval+n,INF);//根据编号从0或是1开始,改+1 
     52     memset(pre,-1,sizeof(pre));
     53     lowval[st]=-1;
     54     pre[st]=-1;
     55     int num=0;//num是目前可以添加到最小生成树中的点的数量 
     56     for(int i=Head[st];i!=-1;i=Edge[i].next)
     57     {
     58         int v=Edge[i].to;
     59         double w=Edge[i].val;
     60         lowval[v]=min(lowval[v],w);
     61         pre[v]=st;
     62         num++;
     63     }
     64     while(num)
     65     {
     66         double MIN=INF;
     67         int k;
     68         for(int i=0;i<n;i++)//根据编号从0或是1开始,改i从0--n-1和1--n
     69         {
     70             if(lowval[i]!=-1&&lowval[i]<MIN)
     71             {
     72                 MIN=lowval[i];
     73                 k=i;
     74             }
     75         }
     76         sum+=MIN;
     77         lowval[k]=-1;
     78         num--;
     79         for(int j=Head[k];j!=-1;j=Edge[j].next)
     80         {
     81             int v=Edge[j].to;
     82             double w=Edge[j].val;
     83             if(w<lowval[v])
     84             {
     85                 if(lowval[v]==INF)
     86                     num++;
     87                 lowval[v]=w;
     88                 pre[v]=k;
     89             }
     90         }
     91     }
     92     for(int i=0;i<n;i++)//判断每个点的pre,看是否有双亲 
     93     {
     94         if(i!=st&&pre[i]==-1)
     95             return INF;
     96     }
     97     return sum;
     98 }
     99 
    100 int main()
    101 {
    102     int T;
    103     scanf("%d",&T);
    104     while(T--)
    105     {
    106         int n;
    107         scanf("%d",&n);
    108         memset(Head,-1,sizeof(Head));
    109         tot=0;
    110         for(int i=0;i<n;i++)
    111             scanf("%d %d",&PT[i].x,&PT[i].y);
    112         for(int i=0;i<n;i++)
    113         {
    114             for(int j=i+1;j<n;j++)
    115             {
    116                 int x=PT[i].x-PT[j].x;
    117                 int y=PT[i].y-PT[j].y;
    118                 double val=sqrt(x*x+y*y);
    119                 if(val>=10&&val<=1000)
    120                 {
    121                     Add_Edge(i,j,val);
    122                     Add_Edge(j,i,val);
    123                 }
    124             }
    125         }
    126         MST=Prim(n,0);
    127         if(MST==INF)
    128             printf("oh!
    ");
    129         else
    130             printf("%.1f
    ",MST*100);
    131     }
    132     return 0;
    133 }
  • 相关阅读:
    css选择器学习(二)属性选择器
    css选择器学习(一)
    css引用优先级
    canvas制图学习
    cookie,localStorage,sessionStorage
    HTTP协议中get和post的区别
    台灯发展史
    Object类实现的方法
    react学习网站
    什么是接口测试,接口测试的目的,如何进行接口测试
  • 原文地址:https://www.cnblogs.com/jiamian/p/11737473.html
Copyright © 2020-2023  润新知