• 2012天津E题


    给我们n个坐标点和一个距离d,表示车开m米就没油了。

    然后要选几个点建立油站,使得能够从1出发遍历所有的点,然后回到1。  并且规定1这个点必须有油站,在第i个点建立油站的费用是 2^(i-1)

    因为费用的特殊性质,如果最大的点能够不建立,那么肯定是不建的。 所以首先在所有的点建立油站,看是否可以遍历所有的点,然后依次从大到小枚举点,看是否可以不建立油站。

    但是卡在如何判断是否能够遍历所有的点上。

    首先判断,所有的油站距离最近的油站的距离不能超过d,  如果超过就不能到达,而且也不能通过没有油站的点中转

    然后,不是油站的点距离最近的油站的距离不能超过d/2 ,这个很显然,如果超过d/2,那么从油站到达这个点,就没办法回去了。

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <queue>
      6 #include <stack>
      7 #include <math.h>
      8 using namespace std;
      9 /*
     10  花费是2^(i-1) 这个很特殊
     11  如何高效得判断是否能经过所有的点然后回家?
     12  */
     13 const int INF = 1<<30;
     14 const int N = 128 + 10;
     15 struct Point
     16 {
     17     int x,y;
     18     double dist(const Point &rhs)
     19     {
     20         return sqrt( (x-rhs.x)*(x-rhs.x)+(y-rhs.y)*(y-rhs.y) );
     21     }
     22 }a[N];
     23 int n,d;
     24 int dist[N][N];
     25 int sta[N];
     26 bool vis[N];
     27 int cnt1,cnt2;
     28 bool bfs()
     29 {
     30     memset(vis,0,sizeof(vis));
     31     int tmp = 0;
     32     for(int i=1;i<=n;++i)
     33         tmp += sta[i];
     34     cnt1 = 1;
     35     cnt2 = 0;
     36     vis[1] = true;
     37     queue<int> q;
     38     q.push(1);
     39     while(!q.empty())
     40     {
     41         int u = q.front();q.pop();
     42         for(int i=2;i<=n;++i)
     43         {
     44             if(!sta[i]) continue;
     45             if(!vis[i] && dist[u][i]<=d)
     46             {
     47                 q.push(i);
     48                 cnt1++;
     49                 vis[i] = true;
     50             }
     51         }
     52     }
     53     for(int i=1;i<=n;++i)
     54         if(sta[i]) q.push(i);
     55     while(!q.empty())
     56     {
     57         int u = q.front(); q.pop();
     58         for(int i=2;i<=n;++i)
     59         {
     60             if(sta[i]) continue;
     61             if(!vis[i] && dist[u][i]*2<=d)
     62             {
     63                 vis[i] = true;
     64                 cnt2++;
     65             }
     66         }
     67     }
     68     if(cnt1==tmp && cnt2==n-tmp) return true;
     69 
     70     return false;
     71 }
     72 int main()
     73 {
     74     //freopen("d:/in.txt","r",stdin);
     75     while(scanf("%d%d",&n,&d)!=EOF)
     76     {
     77         for(int i=1;i<=n;++i)
     78         {
     79             scanf("%d%d",&a[i].x,&a[i].y);
     80             sta[i] = true;
     81         }
     82         for(int i=1;i<=n;++i)
     83         {
     84             for(int j=1;j<=n;++j)
     85                 dist[i][j] = dist[j][i] = (int)ceil(a[i].dist(a[j]));
     86         }
     87         if(bfs())
     88         {
     89 
     90             for(int i=n;i>=2;--i)
     91             {
     92                 sta[i] = false;
     93                 if(!bfs())
     94                     sta[i] = true;
     95             }
     96             while(sta[n]==0) n--;
     97             for(int i=n;i>=1;--i)
     98                 printf("%d",sta[i]);
     99             puts("");
    100         }
    101         else
    102             puts("-1");
    103     }
    104     return 0;
    105 }
  • 相关阅读:
    Redis基础学习(三)—Key操作
    Redis基础学习(二)—数据类型
    Redis基础学习(一)—Redis的安装
    Bootstrap基础学习(二)—表单
    Bootstrap基础学习(一)—表格与按钮
    List去除重复的元素
    jQuery 将表单序列化为Json对象
    SpringMVC基础学习(三)—参数绑定
    CentOS 7.1安装Elasticsearch和Storm
    Python多线程中join函数与setDaemon函数使用说明
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4915741.html
Copyright © 2020-2023  润新知