LA 3270 - Simplified GSM Network

还是觉得应该先把论文刷完

感觉好像掌握了构造维诺图的特殊技巧

论文的方法真是奥妙重重

但是时间复杂度怎么算,我有点方

O(ans)?

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define sqr(x) ((x)*(x))
using namespace std;
const int inf=1e9;
struct point{
	double x,y;
}b[55],c[55];
int B,C;
struct Edge{int to,next,v;}e[20005];
int head[55],cnt;
void ins(int u,int v,int w){
	e[++cnt]=(Edge){v,head[u],w};head[u]=cnt;
}
void insert(int u,int v,int w){
	ins(u,v,w);ins(v,u,w);
}
point getmid(point a,point b){
	return (point){(a.x+b.x)*0.5,(a.y+b.y)*0.5};
}
double dist(point a,point b){
	return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));
}
int belong(point a){
	double ans=1e60;
	int p;
	for(int i=1;i<=B;i++)
	if(dist(a,b[i])<ans)
	ans=dist(a,b[i]),p=i;
	return p;
}
int calc(point a,point b){
	if(belong(a)==belong(b))return 0;
	if(dist(a,b)<1e-6)return 1;
	return calc(a,getmid(a,b))+calc(getmid(a,b),b);
}
int d[55];
bool inq[55];
void spfa(int s){
	memset(d,0x3f,sizeof(d));
	d[s]=0;queue<int>q;q.push(s);
	while(!q.empty()){
		int u=q.front();q.pop();inq[u]=0;
		for(int i=head[u];i;i=e[i].next){
			int v=e[i].to;
			if(d[v]>d[u]+e[i].v){
				d[v]=d[u]+e[i].v;
				if(!inq[v]){
					inq[v]=1;
					q.push(v);
				}
			}
		}
	}
}
int main(){
	//freopen("a.in","r",stdin);
	int R,Q,kase=0;
	while(scanf("%d%d%d%d",&B,&C,&R,&Q)&&B){
		for(int i=1;i<=B;i++)
		scanf("%lf%lf",&b[i].x,&b[i].y);
		for(int i=1;i<=C;i++)
		scanf("%lf%lf",&c[i].x,&c[i].y);
		memset(head,0,sizeof(head));cnt=0;
		while(R--){
			int u,v;scanf("%d%d",&u,&v);
			insert(u,v,calc(c[u],c[v]));
		}
		printf("Case %d:\n",++kase);
		while(Q--){
			int s,t;scanf("%d%d",&s,&t);
			spfa(s);
			if(d[t]>inf)puts("Impossible");
			else printf("%d\n",d[t]);
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值