HDU 2482 Transit search

http://acm.hdu.edu.cn/showproblem.php?pid=2482


#include<iostream>
#include<cmath>
#include<vector>
#include<string>
#include<queue>
using namespace std;
#define N 5050
#define NN 105
#define M 10001
#define inf 0x7fffffff
int place[8]={5120,2560,1280,640,320,160,80,40};
int fx,fy;
int ex,ey;
int m,n;

struct bus_stop{
	int x,y;
	char ch[30];
}B[N];
vector<bus_stop> bus_line[NN];

struct node{
	int next,v,w;
	node(){};
	node(int a,int b,int c){
		next=a;v=b;w=c;
	}
}E[M];
int head[NN],dis[NN],NE;
bool h[NN];
void init(){
	NE=0;
	memset(head,-1,sizeof(head));
}
void insert(int u,int v,int w){
	E[NE]=node(head[u],v,w);
	head[u]=NE++;
}
bool update(int u,int v,int w){
	if(dis[u]+w<dis[v]){
		dis[v]=dis[u]+w;
		return true;
	}
	return false;
}
void spfa(int beg,int end){
	queue<int> q;
	memset(h,0,sizeof(h));
	for(int i=0;i<=m+1;i++)
		dis[i]=inf;
	dis[beg]=0;
	q.push(beg);
	while(!q.empty()){
		int u=q.front();
		q.pop();
		h[u]=0;
		for(int i=head[u];i!=-1;i=E[i].next){
			int v=E[i].v;
			if(update(u,v,E[i].w)&&!h[v]){
				h[v]=1;
				q.push(v);
			}
		}
	}
	if(dis[end]==inf){
		printf("take a taxi\n");
		return;
	}
	printf("%d\n",dis[end]);
}

int find(char *p){
	for(int i=0;i<n;i++)
		if(strcmp(p,B[i].ch)==0)
			return i;
}
bool find_bus(vector<bus_stop> p,vector<bus_stop> q){
	for(int i=0;i<p.size();i++)
		for(int j=0;j<q.size();j++)
			if(strcmp(p[i].ch,q[j].ch)==0)
				return true;
	return false;
}
void trans(char *p,int &x,int &y){
	x*=4;y*=4;
	for(int i=0;i<8;i++){
		if(p[i]=='1')
			y+=place[i];
		else if(p[i]=='2')
			x+=place[i];
		else if(p[i]=='3'){
			x+=place[i];
			y+=place[i];
		}
	}
}
double cal_dis(int fx,int fy,int ex,int ey){
	double temp1=(fx*1.0-ex*1.0)*(fx*1.0-ex*1.0);
	double temp2=(fy*1.0-ey*1.0)*(fy*1.0-ey*1.0);
	return sqrt(temp1+temp2);
}
int main(void){
	int t;
	scanf("%d",&t);
	while(t--){
		char s[10],e[10];
		scanf("%s%d%d",s,&fx,&fy);
		scanf("%s%d%d",e,&ex,&ey);
		trans(s,fx,fy);
		trans(e,ex,ey);
		scanf("%d",&n);
		for(int i=0;i<n;i++){
			scanf("%s",B[i].ch);
			scanf("%d%d",&B[i].x,&B[i].y);
		}
		scanf("%d",&m);
		for(int i=1;i<=m;i++){
			char ch[30];
			int k;
			scanf("%d",&k);
			bus_line[i].clear();
			while(k--){
				scanf("%s",ch);
				int id=find(ch);
				bus_line[i].push_back(B[id]);
			}
		}			
		if(cal_dis(fx,fy,ex,ey)<=2000.0){
			printf("walk there\n");
			continue;
		}
		int beg=0;
		int end=m+1;
		bool flag1,flag2;
		flag1=flag2=0;
		init();
		for(int i=1;i<=m;i++)
			for(int j=0;j<bus_line[i].size();j++){
				double k1=cal_dis(fx,fy,bus_line[i][j].x,bus_line[i][j].y);
				double k2=cal_dis(ex,ey,bus_line[i][j].x,bus_line[i][j].y);
				if(k1<=1000.0){
					flag1=true;
					insert(beg,i,1);
				}
				if(k2<=1000.0){
					flag2=true;
					insert(i,end,0);
				}
			}
		if(!flag1||!flag2){
			printf("take a taxi\n");
			continue;
		}
		for(int i=1;i<=m;i++)
			for(int j=i+1;j<=m;j++)
				if(find_bus(bus_line[i],bus_line[j])){
					insert(i,j,1);
					insert(j,i,1);
				}
		spfa(beg,end);
	}
}
				
				


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值