hdu 4435 charge-station(几何+bfs)

本文介绍了一种通过广度优先搜索(BFS)算法来优化城市间加油站布局的方法。该方法能够确定哪些城市的加油站可以移除而不影响整个交通网络的可达性。通过从最后一个城市逆向测试并确保满足特定距离条件下的可达性,最终实现最小化加油站数量的目标。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最后输出的答案实际上从右往左第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;
}
		
		


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值