二分+最短路 uvalive 3270 Simplified GSM Network(推荐)

  1 // 二分+最短路 uvalive 3270 Simplified GSM Network(推荐)
  2 // 题意:已知B(1≤B≤50)个信号站和C(1≤C≤50)座城市的坐标,坐标的绝对值不大于1000,每个城市使用最近的信号站。给定R(1≤R≤250)条连接城市线路的描述和Q(1≤Q≤10)个查询,求相应两城市间通信时最少需要转换信号站的次数。
  3 // 思路:建议先阅读 NOI论文 <<计算几何中的二分思想>>
  4 // 直接献上题解吧:
  5 // 二分!
  6 // l的两端点所属信号站相同:w[l]=0。
  7 // 否则若|l|<e(蓝):w[l]=1。
  8 // 否则,将线段l沿中点(红)分开:
  9 // l=l1+l2,w[l]=w[l1]+w[l2]。
 10 // 对l1与l2进行同样操作。
 11 // 详细请看论文
 12 
 13 #include <iostream>
 14 #include <algorithm>
 15 #include <cstring>
 16 #include <cstdio>
 17 #include <vector>
 18 #include <cmath>
 19 #include <map>
 20 #include <queue>
 21 using namespace std;
 22 #define LL long long
 23 typedef pair<int,int> pii;
 24 const int inf = 0x3f3f3f3f;
 25 const int MOD = 998244353;
 26 const int N = 1020;
 27 const int maxx = 200010; 
 28 #define clc(a,b) memset(a,b,sizeof(a))
 29 const double eps = 1e-8;
 30 void fre() {freopen("in.txt","r",stdin);}
 31 void freout() {freopen("out.txt","w",stdout);}
 32 inline int read() {int x=0,f=1;char ch=getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch=getchar();}while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}return x*f;}
 33 struct Point{
 34     double x,y;
 35     Point(){}
 36     Point(double _x,double _y){
 37         x = _x;y = _y;
 38     }
 39     Point operator -(const Point &b)const{
 40         return Point(x - b.x,y - b.y);
 41     }
 42     double operator ^(const Point &b)const{
 43         return x*b.y - y*b.x;
 44     }
 45     double operator *(const Point &b)const{
 46         return x*b.x + y*b.y;
 47     }
 48 }b[55],c[55];
 49 int B,C,n,q;
 50 
 51 struct node{
 52     int v,c;
 53     node(int vv,int cc){
 54        v=vv;
 55        c=cc; 
 56     }
 57     node(){}
 58     bool operator <(const node &r) const{
 59         return c>r.c;
 60     }
 61 };
 62 
 63 struct edge{
 64     int v,cost;
 65     edge(int vv=0,int ccost =0):v(vv),cost(ccost){}
 66 };
 67  
 68 vector<edge>e[N];
 69 bool vis[N];
 70 int dist[N];
 71 void dij(int start){
 72     clc(vis,false);
 73     for(int i=0;i<=n+1;i++) dist[i]=inf;
 74     priority_queue<node>q;
 75     while(!q.empty()) q.pop();
 76     dist[start]=0;
 77     q.push(node(start,0));
 78     node tmp;
 79     while(!q.empty()){
 80         tmp=q.top();
 81         q.pop();
 82         int u=tmp.v;
 83         if(vis[u]) continue;
 84         vis[u]=true;
 85         for(int i=0;i<e[u].size();i++){
 86              int v=e[u][i].v;
 87              int cost=e[u][i].cost;
 88              if(!vis[v]&&dist[v]>dist[u]+cost){
 89                 dist[v]=dist[u]+cost;
 90                 q.push(node(v,dist[v]));
 91              }
 92         }
 93     }
 94 }
 95 void add(int u,int v,int w){
 96     e[u].push_back(edge(v,w));
 97 }
 98 
 99 double dis(Point a,Point b){
100     return sqrt((a-b)*(a-b));
101 }
102 
103 int belong(Point a){
104     double len=(double)inf;
105     int num;
106     for(int i=1;i<=B;i++){
107         if(dis(a,b[i])<len){
108             len=dis(a,b[i]),num=i;
109         }
110     }
111     return num;
112 }
113 
114 Point getmid(Point a,Point b){
115     return Point((a.x+b.x)/2,(a.y+b.y)/2);
116 }
117 
118 int calc(Point a,Point b){
119     if(belong(a)==belong(b)) return 0;
120     if(dis(a,b)<1e-6) return 1;
121     else return calc(a,getmid(a,b))+calc(getmid(a,b),b);
122 }
123 
124 int main(){
125     // fre();
126     int cas=1;
127     while(~scanf("%d%d%d%d",&B,&C,&n,&q),B,C,n,q){
128         for(int i=0;i<=1010;i++) e[i].clear();
129         for(int i=1;i<=B;i++){
130             scanf("%lf%lf",&b[i].x,&b[i].y);
131         }
132         for(int i=1;i<=C;i++){
133             scanf("%lf%lf",&c[i].x,&c[i].y);
134         }
135         for(int i=1;i<=n;i++){
136             int u,v;
137             scanf("%d%d",&u,&v);
138             add(u,v,calc(c[u],c[v]));
139             add(v,u,calc(c[v],c[u]));
140         }
141         printf("Case %d:\n",cas++);
142         while(q--){
143             int u,v;
144             scanf("%d%d",&u,&v);
145             dij(u);
146             if(dist[v]>=inf) printf("Impossible\n");
147             else printf("%d\n",dist[v]);
148         }
149     }
150     return 0;
151 }
posted @ 2016-09-14 23:05  yyblues  阅读(336)  评论(0编辑  收藏  举报