• 【bzoj 4449】[Neerc2015]Distance on Triangulation


    Description

    给定一个凸n边形,以及它的三角剖分。再给定q个询问,每个询问是一对凸多边行上的顶点(a,b),问点a最少经过多少条边(可以是多边形上的边,也可以是剖分上的边)可以到达点b。

    Input

    第一行一个整数n(n <= 50000),代表有n个点。点1,2,3,…,n是凸多边形上是顺时针排布的。

    接下来n-3行,每行两个整数(x,y),代表(x,y)之间有一条剖分边。

    接下来是一个整数q(q <= 100000),代表有q组询问。

    接下来q行是两个整数(a,b)。

    Output

    输出q行,每行一个整数代表最少边数。

    运用分治的思想,每一次选择一条剖分边,使得凸多边形分成尽量平均的两部分。使用bfs得出该条边的两个端点到各个顶点的最短路,对所有的询问在两个端点处进行拼凑并更新答案。然后对两部分的信息分别划开,进行下一层的分治。

    (每次分治完,点数会比原来多2,所以空间要开三倍。)

      1 #include<cstdio>
      2 #include<algorithm> 
      3 #include<cstring>
      4 #define LL long long
      5 using namespace std;
      6 const int N=3e5+5;
      7 const int inf=0x3f3f3f3f;
      8 int n,m,cnt,x,y,t,tmp;
      9 int first[N],ans[N],id[N];
     10 int qq[N],disx[N],disy[N],q1[N],q2[N];
     11 bool ok[N];
     12 struct node{int x,y,id;}l[N],q[N],h1[N],h2[N];
     13 struct edge{int to,next;}e[N<<1];
     14 int read()
     15 {
     16     int x=0,f=1;char c=getchar();
     17     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     18     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
     19     return x*f;
     20 }
     21 void ins(int u,int v){e[++cnt]=(edge){v,first[u]};first[u]=cnt;}
     22 int find(int l,int r,int x){return lower_bound(id+l,id+r+1,x)-id;}
     23 void bfs(int S,int pl,int pr,int *dis)
     24 {
     25     int head=0,tail=0;
     26     for(int i=pl;i<=pr;i++)dis[id[i]]=inf;
     27     qq[tail++]=S;dis[S]=0;
     28     while(head!=tail)
     29     {
     30         int u=qq[head++];
     31         for(int i=first[u];i;i=e[i].next)
     32         {
     33             int to=e[i].to;
     34             if(!ok[to])continue;
     35             if(dis[to]==inf)dis[to]=dis[u]+1,qq[tail++]=to;
     36         }
     37     }   
     38 }
     39 void work(int dl,int dr,int pl,int pr,int ql,int qr)
     40 {
     41     if(dl>dr||pl>pr||ql>qr)return;
     42     int mn=inf,mnid=0;
     43     for(int i=dl;i<=dr;i++)
     44     {
     45         x=find(pl,pr,l[i].x);y=find(pl,pr,l[i].y);
     46         if(x>y)swap(x,y);
     47         tmp=max(y-x,x-y+pr-pl+1);
     48         if(tmp<mn)mn=tmp,mnid=i;
     49     }
     50     for(int i=pl;i<=pr;i++)ok[id[i]]=true;
     51     bfs(l[mnid].x,pl,pr,disx);
     52     bfs(l[mnid].y,pl,pr,disy);
     53     for(int i=pl;i<=pr;i++)ok[id[i]]=false;
     54     int t1=0,t2=0,t3=0,t4=0,t5=0,t6=0;
     55     for(int i=ql;i<=qr;i++)
     56     {
     57         x=q[i].x;y=q[i].y;t=q[i].id;
     58         if(x==l[mnid].x&&y==l[mnid].y){ans[t]=1;continue;}
     59         ans[t]=min(ans[t],disx[x]+disx[y]);
     60         ans[t]=min(ans[t],disy[x]+disy[y]);
     61         ans[t]=min(ans[t],disx[x]+disy[y]+1);
     62         ans[t]=min(ans[t],disy[x]+disx[y]+1);
     63         if(q[i].x>l[mnid].x&&q[i].y<l[mnid].y)h1[++t1]=q[i];
     64         else if((q[i].x<l[mnid].x||q[i].x>l[mnid].y)&&
     65         (q[i].y<l[mnid].x||q[i].y>l[mnid].y))h2[++t2]=q[i];
     66     }
     67     for(int i=1;i<=t1;i++)q[ql+i-1]=h1[i];
     68     for(int i=1;i<=t2;i++)q[ql+t1+i-1]=h2[i];
     69     for(int i=pl;i<=pr;i++)
     70     {
     71         if(id[i]>=l[mnid].x&&id[i]<=l[mnid].y)q1[++t3]=id[i];
     72         if(id[i]<=l[mnid].x||id[i]>=l[mnid].y)q2[++t4]=id[i];
     73     }
     74     for(int i=1;i<=t3;i++)id[pl+i-1]=q1[i];
     75     for(int i=1;i<=t4;i++)id[pl+t3+i-1]=q2[i];
     76     for(int i=dl;i<=dr;i++)
     77     {
     78         if(i==mnid)continue;
     79         if(l[i].x>=l[mnid].x&&l[i].y<=l[mnid].y)h1[++t5]=l[i];
     80         else h2[++t6]=l[i];
     81     }
     82     for(int i=1;i<=t5;i++)l[dl+i-1]=h1[i];
     83     for(int i=1;i<=t6;i++)l[dl+t5+i-1]=h2[i];
     84     work(dl+t5,dl+t5+t6-1,pl+t3,pl+t3+t4-1,ql+t1,ql+t1+t2-1);
     85     work(dl,dl+t5-1,pl,pl+t3-1,ql,ql+t1-1); 
     86 }
     87 int main()
     88 {
     89     n=read();
     90     for(int i=1;i<=n-3;i++)
     91     {
     92         l[i].x=read();l[i].y=read();
     93         ins(l[i].x,l[i].y);ins(l[i].y,l[i].x);
     94         if(l[i].x>l[i].y)swap(l[i].x,l[i].y);
     95     }
     96     for(int i=1;i<n;i++)ins(i,i+1),ins(i+1,i);
     97     ins(1,n);ins(n,1);
     98     m=read();
     99     for(int i=1;i<=m;i++)
    100     {
    101         q[i].x=read();q[i].y=read();q[i].id=i;
    102         if(q[i].x>q[i].y)swap(q[i].x,q[i].y);
    103         ans[i]=min(q[i].y-q[i].x,q[i].x-q[i].y+n);
    104     }
    105     for(int i=1;i<=n;i++)id[i]=i;
    106     work(1,n-3,1,n,1,m);
    107     for(int i=1;i<=m;i++)printf("%d
    ",ans[i]);
    108     return 0;
    109 }
    View Code
  • 相关阅读:
    Android Stuido 更新问题
    ListView 获取精确滚动值
    获取ActionBar高度
    AnyncTaskLoader写法
    ScrollView 里面捕获OnTouchMove事件
    ImageLoader displayers 之CircleBitmapDisplayer
    DownloadManager 下载Apk 打开时 解析应用包是出错
    GSON 使用记录
    Android studio 不能升级问题
    一个社交App是如何构建高伸缩性的交互式系统
  • 原文地址:https://www.cnblogs.com/zsnuo/p/8909263.html
Copyright © 2020-2023  润新知