zoukankan      html  css  js  c++  java
  • hdu 4435 第37届ACM/ICPC天津现场赛E题

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 

    题目:给出N个城市,从1开始需要遍历所有点,选择一些点建立加油站,使得花费最少

    这题的特殊性在于他的花费上,2^(i-1)

    利用一个非常重要的性质,2^0+2^1+2^2……+2^i<2^(i+1)

    所有编号<=i的所有点都建,总花费比建一个还少。

    这里就贪心一下,先假设所有点都建,然后依次从编号大的删点,看看能不能遍历整个图

    dist[i]表示点i距离最近的一个加油站的距离

    分析:突破口在于在i号点建立加油站的费用为2^i,这样特殊的花费会使得我们有一个贪心的规律,就是尽量不在号比较大的点建加油站,如果在n号点 建立加油站的费用会大于在除n以外的所有点都建加油站的总费用。所以我们可以先尝试把除n以外的所有点建立加油站,观察是否满足要求。若满足则说明我们必 然不会在n点建立加油站,若不满足我们就一定要在n点建加油站。若需要建,我们就建,然后就不用再考虑n点了,在确定了n点之后,我们用同样的方法来观察 n-1号点是否需要建立加油站,即将1~n-2号点都建立加油站,观察是否满足要求。以此类推,可以推出所有点的情况。

    接下来我们需要解决对于一种给定的加油站建立情况,我们如何判断它是否满足题中的travel around的要求。分为两部判断,1.判断所有加油站是否可达(从1号点开始广搜,若到当前点距离<=d则入队)。2.判断其余点是否可达(刚才 的广搜过程可以顺便标出每个点到最近的加油站的距离,要求能从加油站到该点并返回加油站,所以点到加油站的距离必须小于等于d/2)。若满足这两点必然符 合要求,否则不符合要求。

    2015-05-18:这里的dist维护的是到最近加油站的距离,要是最少肯定所有加油站都要路过

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<queue>
     7 #include<map>
     8 using namespace std;
     9 #define MOD 1000000007
    10 const int INF=0x3f3f3f3f;
    11 const double eps=1e-5;
    12 typedef long long ll;
    13 #define cl(a) memset(a,0,sizeof(a))
    14 #define ts printf("*****
    ");
    15 const int MAXN=130;
    16 int n,m,tt;
    17 int c[MAXN][MAXN],ok[MAXN],vis[MAXN],dist[MAXN],d;
    18 struct Node
    19 {
    20     int x,y;
    21     void in()
    22     {
    23         scanf("%d%d",&x,&y);
    24     }
    25 }node[MAXN];
    26 bool bfs()
    27 {
    28     queue<int> q;
    29     cl(vis);
    30     for(int i=0;i<n;i++)
    31     {
    32         if(ok[i])   dist[i]=0;
    33         else dist[i]=INF;
    34     }
    35     int now;
    36     q.push(0);
    37     vis[0]=1;
    38     while(!q.empty())
    39     {
    40         now=q.front();
    41         q.pop();
    42         for(int i=0;i<n;i++)
    43         {
    44             if(!vis[i]&&c[now][i]<=d)
    45             {
    46                 dist[i]=min(dist[i],dist[now]+c[now][i]);
    47                 if(ok[i])
    48                 {
    49                     q.push(i);
    50                     vis[i]=1;
    51                 }
    52             }
    53         }
    54     }
    55     for(int i=0;i<n;i++)
    56     {
    57         if(ok[i]&&!vis[i])  return 0;
    58         if(!ok[i]&&dist[i]*2>d) return 0;
    59     }
    60     return 1;
    61 }
    62 int main()
    63 {
    64     int i,j,k;
    65     #ifndef ONLINE_JUDGE
    66     freopen("1.in","r",stdin);
    67     #endif
    68     while(scanf("%d%d",&n,&d)!=EOF)
    69     {
    70         for(i=0;i<n;i++)
    71         {
    72             node[i].in();
    73         }
    74         for(i=0;i<n;i++)
    75         {
    76             for(j=0;j<n;j++)
    77             {
    78                 c[i][j]=ceil(sqrt((double)(node[i].x-node[j].x)*(node[i].x-node[j].x)+(node[i].y-node[j].y)*(node[i].y-node[j].y)));
    79             }
    80         }
    81         for(i=0;i<n;i++)    ok[i]=1;
    82         if(!bfs())
    83         {
    84             puts("-1");
    85             continue;
    86         }
    87         for(i=n-1;i>0;i--)
    88         {
    89             ok[i]=0;
    90             if(!bfs())  ok[i]=1;
    91         }
    92         j=n-1;
    93         while(!ok[j])      j--;
    94         for(i=j;i>=0;i--)   printf("%d",ok[i]);
    95         puts("");
    96     }
    97 }
  • 相关阅读:
    112、TensorFlow初始化变量
    111、TensorFlow 初始化变量
    110、TensorFlow张量值的计算
    109、TensorFlow计算张量的值
    108、TensorFlow 类型转换
    107、TensorFlow变量(三)
    106、TensorFlow变量 (二) reshape
    105、TensorFlow的变量(一)
    104、Tensorflow 的变量重用
    103、Linux 编译 Kaldi 语音识别工具
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4436402.html
Copyright © 2011-2022 走看看