题目大意:有一个国王他开着一辆最大只能行驶d距离的车子(因为行驶完d距离后车子就没油了)环游世界,他想从1点出发环游到n点再回来,由于车子的原因,他必须在某几个点上建加油站,来保证它能够顺利的环游世界,但是在第i个点建立加油站的费用为2^i,因此问你如何建站能使所需要的费用最小,如果怎么建站也不行的话就输出-1。
算法思想:假设我们再每个点都建站,如果这样都不能完成的话,那么肯定输出-1,否则,我们就从第n个点开始,判断第n个点是否需要建加油站,如果少了这个加油站不能完成的话,那么这个点必须要建站,然后在判断第n-1个点,n-2个点,一直到第2个点(因为第一个点根据题目要求必须要建站)。
那么如何判断是否完成呢?因为每次都从1点开始,我们先把1点如队列,然后我们就从1点开始更新与1点相接的所有点的距离,如果是加油站,则再把他入队,否则更新该点的最短距离,直到队列为空。这样的话,我们到最后可以这样判断是否完成:如果该点不是加油站,但是他的最短距离超过了d/2(因为要往返)或者该点是加油站,但是这个加油站没有被访问到,说明该点没有被访问过,则不能完成,反之,则能完成。
#include <iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
#define MAXN 130
#define INF 0x3f3f3f3f
typedef struct Node
{
int x;
int y;
};
Node nodes[MAXN];
int n,d;
double a[MAXN][MAXN],dist[MAXN];//dist数组表示当前点到最近的加油站的距离
bool visited[MAXN],flag[MAXN];
double calc(int l,int r)
{
return sqrt((nodes[l].x-nodes[r].x)*(nodes[l].x-nodes[r].x)+(nodes[l].y-nodes[r].y)*(nodes[l].y-nodes[r].y));
}
bool travel()
{
queue<int>que;
memset(visited,false,sizeof(visited));
for(int i=1;i<=n;i++)
{
if(flag[i])
dist[i]=0;
else
dist[i]=INF;
}
visited[1]=true;
que.push(1);
while(!que.empty())
{
int k=que.front();
que.pop();
for(int i=1;i<=n;i++)
{
if(!visited[i]&&a[k][i]<=d)
{
dist[i]=min(dist[i],dist[k]+a[k][i]);
if(flag[i])
{
visited[i]=true;
que.push(i);
}
}
}
}
for(int i=1;i<=n;i++)
{
if(!flag[i]&&dist[i]>d/2)
return false;
if(flag[i]&&!visited[i])
return false;
}
return true;
}
int main()
{
while(scanf("%d%d",&n,&d)!=EOF)
{
memset(flag,false,sizeof(flag));
//memset(visited,false,sizeof(visited));
memset(nodes,0,sizeof(nodes));
for(int i=1;i<=n;i++)
{
scanf("%d%d",&nodes[i].x,&nodes[i].y);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
a[i][j]=calc(i,j);
}
}
for(int i=1;i<=n;i++)
{
flag[i]=true;//假设一开始都有加油站
}
if(!travel())//在每个点都有加油站的情况下还不能走到的话就说明肯定不能走到
{
printf("-1\n");
continue;
}
for(int i=n;i>1;i--)
{
flag[i]=false;
if(!travel())
flag[i]=true;
}
int f=0;
for(int i=n;i>=1;i--)
{
if(flag[i])
{
f=i;
break;
}
}
for(int i=f;i>=1;i--)
{
if(flag[i])
printf("%d",1);
else
printf("%d",0);
}
printf("\n");
}
return 0;
}