hdu 4435 charge-station(几何+bfs)

最后输出的答案实际上从右往左第i位就代表第i个城市是否有加油站。

首先要写一个bfs函数判断一个图能否满足题目要求: 

dfs时从第一个城市开始,设bfs到当前城市cur,如果cur无加油站则不能判断从它能到达哪个城市,直接continue。对于其他每个城市i,如果i有加油站,那么和cur的距离只要小于D就可以被访问到,如果i没有加油站,那么和cur距离需要小于D/2(因为到i后还需要返回cur)。最后如果没有把所有城市都遍历到就不行。


然后从最后一个城市开始测试能否删除,首先必须要有一个有加油站的城市与它距离小于D/2才可能删。满足这个条件后还要调用bfs确认整个图是否可行。如果都可行就删除。


最后倒序输出就是答案。


代码:

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <cmath>
using namespace std;
#define eps 1e-7
int N,D;
struct node {
	int x,y;
}G[130];
bool vis[130];
bool exist[130];
double dist(int a,int b){
	double tx=G[a].x-G[b].x;
	double ty=G[a].y-G[b].y;
	return ceil(sqrt(tx*tx+ty*ty));
}

bool bfs(){
	queue <int> Q;
	Q.push(1);
	memset(vis,0,sizeof(vis));
	vis[1]=1;
	while(!Q.empty()){
		int cur=Q.front();
		Q.pop();
		if(exist[cur]){
			for(int i=1;i<=N;i++){
				if(!vis[i]&&exist[i]){
					if(dist(i,cur)<D+eps){
						vis[i]=1;
						Q.push(i);
					}
				}
				else if(!vis[i]&&!exist[i]){
					if(dist(i,cur)<D/2+eps){
						vis[i]=1;
						Q.push(i);
					}
				}
			}
	    }
	}
	for(int i=1;i<=N;i++){
		if(!vis[i])  return 0;
	}
	return 1;
}
	
		
		
	
void solve(){
	for(int i=N;i>=1;i--){
		for(int j=1;j<=N;j++){
			if(exist[j]&&dist(i,j)<D/2+eps){
				if(i==j)continue;
				exist[i]=0;
				if(!bfs()){
					exist[i]=1;
				}
			}
		}
	}
}

int main(){
	while(~scanf("%d%d",&N,&D)){
		for(int i=1;i<=N;i++){
			exist[i]=1;
			scanf("%d%d",&G[i].x,&G[i].y);
		}
		if(!bfs()){
			printf("-1\n");
			continue;
		}
		solve();
		bool flag=0;
		exist[1]=1;
		for(int i=N;i>=1;i--){
			if(exist[i]) flag=1;
			if(flag){
				if(exist[i])printf("1");
				else printf("0");
			}
		}
		printf("\n");
	}
	return 0;
}
		
		


你可能感兴趣的:(bfs)