zoukankan      html  css  js  c++  java
  • [差分][倍增lca][tarjan] Jzoj P3325 压力

    Description

    如今,路由器和交换机构建起了互联网的骨架。处在互联网的骨干位置的核心路由器典型的要处理100Gbit/s的网络流量。他们每天都生活在巨大的压力之下。
    小强建立了一个模型。这世界上有N个网络设备,他们之间有M个双向的链接。这个世界是连通的。在一段时间里,有Q个数据包要从一个网络设备发送到另一个网络设备。
    一个网络设备承受的压力有多大呢?很显然,这取决于Q个数据包各自走的路径。不过,某些数据包无论走什么路径都不可避免的要通过某些网络设备。
    你要计算:对每个网络设备,必须通过(包括起点、终点)他的数据包有多少个?
     

    Input

    第一行包含3个由空格隔开的正整数N,M,Q。
    接下来M行,每行两个整数u,v,表示第u个网络设备(从1开始编号)和第v个网络设备之间有一个链接。u不会等于v。两个网络设备之间可能有多个链接。
    接下来Q行,每行两个整数p,q,表示第p个网络设备向第q个网络设备发送了一个数据包。p不会等于q。

    Output

    输出N行,每行1个整数,表示必须通过某个网络设备的数据包的数量。
     

    Sample Input

    4 4 2
    1 2
    1 3
    2 3
    1 4
    4 2
    4 3

    Sample Output

    2
    1
    1
    2
    【样例解释】
    设备1、2、3之间两两有链接,4只和1有链接。4想向2和3各发送一个数据包。显然,这两个数据包必须要经过它的起点、终点和1。
     
     

    Data Constraint

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

    题解

    • 题目大意:给出一个 N 个点,M 条边的连通图,和 M 个点对。询问删掉每个点会使 M 个点对中的几个不连通
    • 其实就类似于求路径上有多少个割点
    • 首先,可以tarjan求点双分量,然后建新点,也就是缩点
    • 最后得到一颗树
    • 然后就在树上求两点的lca
    • 最后就是差分了
    • 那么怎么做?
    • 将x,y点++,lca--,lca的父亲--
    • 那么怎么处理在路径上的割点呢?
    • 在倍增时,记录对于新建点的父亲
    • 那新建点也就是缩点后的点与父亲只有一条路径
    • 那么就可以将父亲的差分+当前点的差分,一步一步将树向上加

    代码

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<queue>
     7 #include<vector>
     8 using namespace std;
     9 struct edge {int to,from; }e[200010*2],c[200010*2];
    10 int n,m,q,dis,tot,cnt,num,cnt1,cnt2,head[200010],last[200010],dfn[100010],low[100010],k[100010],sh[200010],f[200010][21],dep[200010],d[200010];
    11 void insert(int x,int y) { e[++cnt].to=y; e[cnt].from=head[x]; head[x]=cnt; }
    12 void insert1(int x,int y) { c[++cnt2].to=y; c[cnt2].from=last[x]; last[x]=cnt2; }
    13 void tarjan(int x)
    14 {
    15     dfn[x]=low[x]=++cnt1; k[++num]=x;
    16     for (int i=head[x];i;i=e[i].from)
    17     {
    18         int v=e[i].to;
    19         if (dfn[v]==-1)
    20         {
    21             tarjan(v);
    22             low[x]=min(low[x],low[v]);
    23             if (low[v]>=dfn[x])
    24             {
    25                 tot++;
    26                 int j;
    27                 do
    28                 {
    29                     j=k[num--]; 
    30                     insert1(tot,j); insert1(j,tot);
    31                 }
    32                 while (j!=v);
    33                 insert1(x,tot);insert1(tot,x);
    34             }
    35         }
    36         else low[x]=min(low[x],dfn[v]);
    37     }
    38 }
    39 void dfs(int x,int fa)
    40 {
    41     sh[sh[0]++]=x; f[x][0]=fa;
    42     for (int i=1;i<=20;i++) f[x][i]=f[f[x][i-1]][i-1];
    43     for (int i=last[x];i;i=c[i].from)
    44     {
    45         int v=c[i].to;
    46         if (v==fa) continue;
    47         dep[v]=dep[x]+1;
    48         dfs(v,x);
    49     }
    50 }
    51 int lca(int x,int y)
    52 {
    53     if (dep[x]>dep[y]) swap(x,y);
    54     for (int i=20;i>=0;i--)
    55         if (dep[f[y][i]]>=dep[x])
    56             y=f[y][i];
    57     if (x==y) return x;
    58     for (int i=20;i>=0;i--)
    59         if (f[x][i]!=f[y][i])
    60             x=f[x][i],y=f[y][i];
    61     return f[x][0];
    62 }
    63 int main()
    64 {
    65     scanf("%d%d%d",&n,&m,&q);
    66     tot=n;
    67     for (int i=1;i<=m;i++)
    68     {
    69         int u,v;    
    70         scanf("%d%d",&u,&v);
    71         insert(u,v); insert(v,u);
    72     }
    73     memset(dfn,-1,sizeof(dfn));
    74     tarjan(1);
    75     dep[1]=1; dfs(1,0);
    76     for (int i=1;i<=q;i++)
    77     {
    78         int x,y;
    79         scanf("%d%d",&x,&y);
    80         dis=lca(x,y);
    81         d[x]++; d[y]++; d[dis]--; d[f[dis][0]]--;
    82     }
    83     for (int i=tot;i>=1;i--) 
    84     {
    85         int now=sh[i];
    86         d[f[now][0]]+=d[now];
    87     }
    88     for (int i=1;i<=n;i++) printf("%d
    ",d[i]);
    89     return 0;
    90 }
  • 相关阅读:
    Jmeter 使用技巧 (如何在linux下运行jmeter视窗界面呢)-jmeter如何模拟http发送gzip数据
    1.Jmeter 快速入门教程(一)
    4.jmeter在线并发的怎样设置
    3.jmeter jsr232 脚本获取当前测试的正在活动的线程数
    2.Jmeter 如何在jsr223 脚本中停止测试任务
    1.如何在JMeter中使用JUnit
    app电量测试
    梯度下降法实现对数几率回归
    基于C/S模式的简易聊天室
    大数据使用及现状调研报告
  • 原文地址:https://www.cnblogs.com/Comfortable/p/9281112.html
Copyright © 2011-2022 走看看