zoukankan      html  css  js  c++  java
  • 【BZOJ】1969: [Ahoi2005]LANE 航线规划

    题目链接:

      传送~~

    题解:

        老夫实在是码不动了……

      正着搞显然不好做,尝试倒着乱搞。先给被删除的边标记一个时间戳,先删除的时间戳大,同时维护询问时间戳,询问早的时间戳大。没被删除过的边时间戳都是0。然后瞎tarjan一次,建立双联通分量树。然后考虑每条被删除的边补会图中,相当于把两点所属双联通分量之间路径边权变为0。然后强行树剖一波即可。

      (调死人啦!

    代码:

     

      1 #define Troy 10/19/2017
      2 
      3 #include <bits/stdc++.h>
      4 
      5 using namespace std;
      6 
      7 inline int read(){
      8     int s=0,k=1;char ch=getchar();
      9     while(ch<'0'|ch>'9')    ch=='-'?k=-1:0,ch=getchar();
     10     while(ch>47&ch<='9')    s=s*10+(ch^48),ch=getchar();
     11     return s*k;
     12 }
     13 
     14 const int N=1e5+8;
     15 
     16 int n,m,q,ans[N];
     17 
     18 struct Q{
     19     int u,v,times,val;
     20     inline void in(){
     21         u=read(),v=read(),val=0;
     22         if(u>v)    swap(u,v);
     23     }
     24 }query[N<<1];
     25 
     26 inline bool cmpx(Q a,Q b){
     27     return a.u!=b.u?a.u<b.u:a.v<b.v;
     28 }
     29 
     30 inline bool cmpy(Q a,Q b){
     31     return a.times<b.times;
     32 }
     33 
     34 struct edges{ 
     35     int v;edges *last;
     36 }edge[N<<2],*head[N];int cnt;
     37 
     38 inline void push(int u,int v){
     39     edge[++cnt]=(edges){v,head[u]};head[u]=edge+cnt;
     40 }
     41 
     42 /**********************************************************************/
     43 
     44 int dfn[N],low[N],bccno[N],idx,stk[N],top,bcc_cnt;
     45 
     46 inline void tarjan(int x,int fa){
     47     dfn[x]=low[x]=++idx;
     48     stk[++top]=x;
     49     for(edges *i=head[x];i;i=i->last)    if(i->v!=fa){
     50         if(!dfn[i->v]){
     51             tarjan(i->v,x);
     52             low[x]=min(low[x],low[i->v]);
     53         }else
     54             low[x]=min(low[x],dfn[i->v]);
     55     }
     56     if(dfn[fa]<low[x]){
     57         bcc_cnt++;int t;
     58         do{
     59             t=stk[top--];
     60             bccno[t]=bcc_cnt;
     61         }while(t!=x);
     62     }
     63 }
     64 
     65 /*****************************************************************/
     66 int size[N],heavy[N],deep[N],g[N],f[N],tid[N];
     67 
     68 inline void dfs(int x,int fa){
     69     size[x]=1;
     70     for(edges *i=head[x];i;i=i->last)if(i->v!=fa){
     71         deep[i->v]=deep[x]+1;
     72         f[i->v]=x;
     73         dfs(i->v,x);
     74         size[x]+=size[i->v];
     75         if(size[i->v]>size[heavy[x]])
     76             heavy[x]=i->v;
     77     }
     78 }
     79 
     80 inline void dfs(int x,int fa,int grand){
     81     tid[x]=++idx;
     82     g[x]=grand;
     83     if(heavy[x])
     84         dfs(heavy[x],x,grand);
     85     for(edges *i=head[x];i;i=i->last)
     86         if(i->v!=fa&&i->v!=heavy[x])
     87             dfs(i->v,x,i->v);
     88 }
     89 
     90 inline void init(){
     91     n=read(),m=read();
     92     for(int i=1;i<=m;i++)
     93         query[i].in();
     94     sort(query+1,query+1+m,cmpx);
     95     int t=1e6;
     96     while(1){
     97         int c=read(),a,b;
     98         if(c==-1)    break;
     99         a=read(),b=read();
    100         if(a>b)    swap(a,b);
    101         if(c==0){
    102             int x=upper_bound(query+1,query+1+m,(Q){a,b,0,0},cmpx)-query-1;
    103             query[x].times=t;
    104         }else{
    105             q++;
    106             query[q+m]=(Q){a,b,t,1};
    107         }
    108         t--;
    109     }
    110     sort(query+1,query+1+q+m,cmpy);
    111     for(int i=1;i<=m+q&&query[i].times==0;i++)
    112         push(query[i].u,query[i].v),
    113         push(query[i].v,query[i].u);
    114     tarjan(1,0);
    115     memset(head,0,sizeof(head));cnt=0;
    116     for(int i=1;i<=m+q&&query[i].times==0;i++)
    117         if(bccno[query[i].u]!=bccno[query[i].v])
    118             push(bccno[query[i].u],bccno[query[i].v]),
    119             push(bccno[query[i].v],bccno[query[i].u]);    
    120     dfs(1,1);    
    121     idx=0;
    122     dfs(1,1,1);
    123 }
    124 
    125 /********************************************************************/
    126 
    127 struct Tree{
    128     Tree *son[2];
    129     int val;
    130 }*root,tree[N<<2];int t_cnt;
    131 
    132 inline void build(Tree *&u,int l,int r){
    133     u=tree+t_cnt;t_cnt++;
    134     u->val=0;
    135     if(l==r){
    136         u->son[0]=u->son[1]=NULL;
    137         u->val=(l!=1);
    138         return;
    139     }
    140     int mid=l+r>>1;
    141     build(u->son[0],l,mid);
    142     build(u->son[1],mid+1,r);
    143     for(int i=0;i<2;i++)
    144         u->val+=u->son[i]->val;
    145 }
    146 
    147 inline void change(Tree *u,int l,int r,int x,int y){
    148     if((x<=l&&r<=y)||u->val==0){    
    149         u->val=0;
    150         return;
    151     }
    152     int mid=l+r>>1;
    153     if(y>mid)
    154         change(u->son[1],mid+1,r,x,y);
    155     if(x<=mid)
    156         change(u->son[0],l,mid,x,y);
    157     u->val=0;
    158     for(int i=0;i<2;i++)
    159         u->val+=u->son[i]->val;
    160 }
    161 
    162 inline int sum(Tree *u,int l,int r,int x,int y){
    163     if(u->val==0)    return 0;    
    164     if(x<=l&&r<=y)
    165         return u->val;
    166     int mid=l+r>>1;
    167     if(x>mid)
    168         return sum(u->son[1],mid+1,r,x,y);
    169     else    if(y<=mid)
    170         return sum(u->son[0],l,mid,x,y);
    171     else    return sum(u->son[0],l,mid,x,y)+sum(u->son[1],mid+1,r,x,y);
    172 }
    173 
    174 inline void change(int x,int y){
    175     while(g[x]!=g[y]){
    176         if(deep[g[x]]<deep[g[y]])
    177             swap(x,y);
    178         change(root,1,idx,tid[g[x]],tid[x]);        
    179         x=f[g[x]];
    180     }
    181     if(x==y)    return;
    182     if(deep[x]>deep[y])
    183         swap(x,y);
    184     change(root,1,idx,tid[x]+1,tid[y]);
    185 }
    186 
    187 inline int sum(int x,int y){
    188     int ret=0;
    189     while(g[x]!=g[y]){
    190         if(deep[g[x]]<deep[g[y]])
    191             swap(x,y);
    192         ret+=sum(root,1,idx,tid[g[x]],tid[x]);
    193         x=f[g[x]];
    194     }
    195     if(x!=y){
    196         if(deep[x]>deep[y])
    197             swap(x,y);
    198         ret+=sum(root,1,idx,tid[x]+1,tid[y]);
    199     }
    200     return ret;
    201 }
    202 
    203 inline void work(){
    204     build(root,1,idx);
    205     int t=q;
    206     for(int i=1;i<=m+q;i++)
    207         if(query[i].times==0)
    208             continue;
    209         else{
    210             if(query[i].val==0){
    211                 change(bccno[query[i].u],bccno[query[i].v]);
    212             }
    213             else{
    214                 ans[t]=sum(bccno[query[i].u],bccno[query[i].v]);
    215                 t--;
    216             }
    217         }
    218     for(int i=1;i<=q;i++)
    219         printf("%d
    ",ans[i]);
    220 }
    221 
    222 int main(){
    223     init();
    224     work();
    225 }
  • 相关阅读:
    冲刺——第三天
    冲刺——第二天
    梦断代码前三章略有感想
    四则运算法则设计思路
    第一期阅读计划
    软件工程概论第一次课堂小测-------产生30个100以内的随机整数四则运算的小程序
    软件演化
    软件测试
    软件实现
    面向对象设计
  • 原文地址:https://www.cnblogs.com/Troywar/p/7693887.html
Copyright © 2011-2022 走看看