• BZOJ 压力 tarjan 点双联通分量+树上差分+圆方树


    题意

    如今,路由器和交换机构建起了互联网的骨架。处在互联网的骨干位置的核心路由器典型的要处理100Gbit/s的网络流量。

    他们每天都生活在巨大的压力之下。小强建立了一个模型。这世界上有N个网络设备,他们之间有M个双向的链接。这个世界是连通的。

    在一段时间里,有Q个数据包要从一个网络设备发送到另一个网络设备。
    一个网络设备承受的压力有多大呢?很显然,这取决于Q个数据包各自走的路径。

    不过,某些数据包无论走什么路径都不可避免的要通过某些网络设备。
    你要计算:对每个网络设备,必须通过(包括起点、终点)他的数据包有多少个?

    对于40%的数据,N,M,Q≤2000
    对于60%的数据,N,M,Q≤40000
    对于100%的数据,N≤100000,M,Q≤200000

    分析

      这道题很有意思,如果它要是问可能通过的点有多少个,那问题就麻烦多了,所以它问必须经过的点,对于一个点来说,如果它不是割点,那么它一定不是必经的,除非它是端点,所以我们想到了什么?对点双联通分量,但是如果全缩了还是有问题,必须经过的点怎么办?如果变换一下这个图,让它两个点之间有唯一的路径,是不是就很好办了,对于唯一路径,我们很容易想到树,而又不能全缩了成为树,那就势必要用到别的树。

      所以引入一个新的树——圆方树

      这个树其实很好理解,就是原图的每个点都是圆点,方点是什么呢?一个方点对应一个点双联通分量,每个点双上的点连到这个这个方点上,这样就形成了一棵树,然后怎么办呢?如果对于每次修改都dfs一遍,显然效率是不高的,而每次发送一回数据包,就是将这一个经过的路径区间val+1,涉及区间加减,不就是差分数组嘛,所以直接u++,v++,lca--,falca--(点差分是falca--因为lca的值也要更新,边差分是lca-=2因为lca上边连着父亲节点的边是不改变的),最后直接dfs跑一遍统计答案就ok。

      这里特别强调一个坑,点双连树的时候不要直接pop到割点,而是要pop到E.to,看起来是差不多的,但是在割点到E.to之间,还可能会有点,这里说的有点不是图上边,而是栈里边有没pop的值,点没有pop的原因是没有判断到割点,而那些点是显然不是这个点双里边的,连进来就是,WA,所以这里要特别注意一下。

      

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<algorithm>
     4 using namespace std;
     5 const int N=4e5+1;
     6 struct Edge{
     7     int to,next;
     8 }e[N],E[N];
     9 int Head[N],len;
    10 void Ins(int a,int b){
    11     e[++len].to=b;e[len].next=Head[a];Head[a]=len;
    12 }
    13 int H[N],l;
    14 void I(int a,int b){
    15     E[++l].to=b;E[l].next=H[a];H[a]=l;
    16 }
    17 int low[N],dfn[N],stk[N],num,top,fang;
    18 void tarjan(int u){
    19     dfn[u]=low[u]=++num;
    20     stk[++top]=u;
    21     for(int x=Head[u];x;x=e[x].next){
    22         int v=e[x].to;
    23         if(!dfn[v]){
    24             tarjan(v);
    25             low[u]=min(low[u],low[v]);
    26             if(low[v]>=dfn[u]){
    27                 fang++;int temp;
    28                 do{
    29                     temp=stk[top--];
    30                     I(temp,fang);I(fang,temp);
    31                 }while(temp!=v);//是这里不能pop到u
    32                 I(fang,u);I(u,fang);
    33             }
    34         }else low[u]=min(low[u],dfn[v]);
    35     }
    36 }
    37 int p[N][30],dep[N];
    38 //跑lca
    39 void dfs(int x){
    40     for(int i=0;p[x][i];i++)
    41         p[x][i+1]=p[p[x][i]][i];
    42     for(int i=H[x];i;i=E[i].next){
    43         int v=E[i].to;
    44         if(v!=p[x][0]){
    45             p[v][0]=x;
    46             dep[v]=dep[x]+1;
    47             dfs(v);
    48         }
    49     }
    50 }
    51 int Lca(int u,int v){
    52     if(dep[u]<dep[v])swap(u,v);
    53     int d=dep[u]-dep[v];
    54     for(int i=0;d;i++,d>>=1)
    55         if(d&1)u=p[u][i];
    56     if(u==v)return u;
    57     for(int i=20;i>=0;i--)//这里又写错了刚开始,i>=0不是i,i->i>0少了个0
    58         if(p[u][i]!=p[v][i])
    59             u=p[u][i],v=p[v][i];
    60     return p[u][0];
    61 }
    62 //lca结束
    63 int val[N];
    64 int calc(int u){
    65     for(int i=H[u];i;i=E[i].next){
    66         int v=E[i].to;
    67         if(v!=p[u][0])
    68             val[u]+=calc(v);
    69     }
    70     return val[u];
    71 }
    72 int main(){
    73 //    freopen("a.txt","r",stdin);
    74     int m,n,q;
    75     scanf("%d%d%d",&n,&m,&q);
    76     fang=n;
    77     for(int i=1;i<=m;i++){
    78         int a,b;
    79         scanf("%d%d",&a,&b);
    80         Ins(a,b);Ins(b,a);
    81     }
    82     tarjan(1);//图是联通的tarjan一遍就好
    83     dfs(1);
    84     while(q--){
    85         int a,b;
    86         scanf("%d%d",&a,&b);
    87         int lca=Lca(a,b);
    88         val[a]++;val[b]++;
    89         val[lca]--;val[p[lca][0]]--;//树上差分
    90     }
    91     calc(1);
    92     for(int i=1;i<=n;i++)
    93         printf("%d
    ",val[i]);
    94 }
  • 相关阅读:
    ES6标准入门 第一章:简介
    vue调试工具之 vue-devtools的安装
    vue 高德地图之玩转周边
    vue-动手做个选择城市
    js 高级算法
    (转)预处器的对比——Sass、LESS和Stylus
    windows下安装mongodb以及node.js连接mongodb
    vue组件(将页面公用的头部组件化)
    浅谈移动端rem的用法
    vue 调用高德地图
  • 原文地址:https://www.cnblogs.com/anyixing-fly/p/12449661.html
Copyright © 2020-2023  润新知