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 }

 

posted @ 2015-10-27 22:00  justPassBy  阅读(148)  评论(0编辑  收藏  举报