3331: [BeiJing2013]压力

LCA+树上差分,和之前类似的题差不多,就是多了个v-dcc缩点,唯一要注意的就是判断是否是割点,对于不是割点的点,如果他是起点或重点,ans++,和差分没有关系,对于割点,则需要用到差分,注意割点与非割点的答案要分开存储,否则会死的。

另外要注意的是数组的大小,开始我因为数组开小了然后MLE了(对,就是这么神奇),因为如果退化成一条链,缩完点后的点数会比缩点前还要多。

#include<iostream>
#include<cstdio>
#include<vector>
#define MAXN 300010
using namespace std;
struct edge
{
int u,v,nxt;
#define u(x) ed[x].u
#define v(x) ed[x].v
#define n(x) ed[x].nxt
#define u2(x) ed2[x].u
#define v2(x) ed2[x].v
#define n2(x) ed2[x].nxt
}ed[MAXN*4],ed2[MAXN*4];
int first[MAXN],num_e;
#define f(x) first[x]
int first2[MAXN],num_e2;
#define f2(x) first2[x]
int n,m,q; int dfn[MAXN],low[MAXN],num,root;
int stack[MAXN],top,cnt;
bool iscut[MAXN];
vector<int> dcc[MAXN];
void tarjan(int x)
{
dfn[x]=low[x]=++num;
stack[++top]=x;
if(x==root&&!f(x)){dcc[++cnt].push_back(x);return;}
int flag=0;
for(int i=f(x);i;i=n(i))
if(!dfn[v(i)])
{
tarjan(v(i));low[x]=min(low[x],low[v(i)]);
if(low[v(i)]>=dfn[x])
{
flag++;
if(x!=root||flag>1)iscut[x]=1;
cnt++;int z;
do{dcc[cnt].push_back(z=stack[top--]);}while(z!=v(i));
dcc[cnt].push_back(x);
}
}
else low[x]=min(low[x],dfn[v(i)]);
}
int new_id[MAXN],c[MAXN];
int f[MAXN][20],dep[MAXN];
void dfs(int x,int fa,int deep)
{
f[x][0]=fa;dep[x]=deep;
for(int i=f2(x);i;i=n2(i))
if(v2(i)!=fa)
dfs(v2(i),x,deep+1);
}
int ans[MAXN],eans[MAXN];
void dfs2(int x,int fa)
{
for(int i=f2(x);i;i=n2(i))
if(v2(i)!=fa)
{
dfs2(v2(i),x);
eans[x]+=eans[v2(i)];
}
}
int LCA(int x,int y)
{
if(dep[x]>dep[y])swap(x,y);
while(dep[x]!=dep[y])
for(int i=0;;i++)
if(dep[f[y][i]]<dep[x])
{y=f[y][i-1];break;}
if(x==y)return x;
while(f[x][0]!=f[y][0])
for(int i=0;;i++)
if(f[x][i]==f[y][i])
{x=f[x][i-1],y=f[y][i-1];break;}
return f[x][0];
}
inline void add(int u,int v);
inline void add2(int u,int v);
signed main()
{
// freopen("in.txt","r",stdin); scanf("%d%d%d",&n,&m,&q);
int a,b;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
add(a,b),add(b,a);
}
for(int i=1;i<=n;i++)
if(!dfn[i]){root=i;tarjan(i);}
num=cnt;
for(int i=1;i<=n;i++)
if(iscut[i])new_id[i]=++num;
for(int i=1;i<=cnt;i++)
for(int j=0;j<dcc[i].size();j++)
{
int x=dcc[i][j];
if(iscut[x])
add2(i,new_id[x]),add2(new_id[x],i);
else c[dcc[i][j]]=i;
}
dfs(1,0,1);
for(int j=1;j<20;j++)
for(int i=1;i<=num;i++)
f[i][j]=f[f[i][j-1]][j-1];
for(int i=1;i<=q;i++)
{
scanf("%d%d",&a,&b);
if(!iscut[a])ans[a]++;
if(!iscut[b])ans[b]++;
int ca=iscut[a]?new_id[a]:c[a],
cb=iscut[b]?new_id[b]:c[b],
lca=LCA(ca,cb);
eans[ca]++,eans[cb]++;
eans[f[lca][0]]--,eans[lca]--;
}
dfs2(1,0);
for(int i=1;i<=n;i++)
printf("%d\n",iscut[i]?eans[new_id[i]]:ans[i]);
}
inline void add(int u,int v)
{
++num_e;
u(num_e)=u;
v(num_e)=v;
n(num_e)=f(u);
f(u)=num_e;
}
inline void add2(int u,int v)
{
++num_e2;
u2(num_e2)=u;
v2(num_e2)=v;
n2(num_e2)=f2(u);
f2(u)=num_e2;
}

3331: [BeiJing2013]压力的更多相关文章

  1. bzoj 3331: [BeiJing2013]压力

    Description 如今,路由器和交换机构建起了互联网的骨架.处在互联网的骨干位置的 核心路由器典型的要处理100Gbit/s的网络流量.他们每天都生活在巨大的压力 之下. 小强建立了一个模型.这 ...

  2. BZOJ 3331 [BeiJing2013]压力-Tarjan + 树上差分

    Solution Tarjan 点双缩点, 加上树上差分计算. 注意特判... 我特判挂了好久呜呜呜 Code #include<cstdio> #include<cstring&g ...

  3. 【BZOJ3331】[BeiJing2013]压力 Tarjan求点双

    [BZOJ3331][BeiJing2013]压力 Description 如今,路由器和交换机构建起了互联网的骨架.处在互联网的骨干位置的核心路由器典型的要处理100Gbit/s的网络流量.他们每天 ...

  4. BZOJ3331: [BeiJing2013]压力

    传送门 Tarjan的三大应用之一:求解点双联通分量. 求解点双联通分量.然后缩点,差分优化即可. //BZOJ 3331 //by Cydiater //2016.10.29 #include &l ...

  5. BZOJ3331 [BeiJing2013]压力[圆方树+树上差分]

    圆方树新技能get.具体笔记见图连通性问题学习笔记. 这题求无向图的必经点,这个是一个固定套路:首先,一张连通的无向图中,每对点双和点双之间是以一个且仅一个割点连接起来的(如果超过一个就不能是割点了) ...

  6. Solution -「BZOJ 3331」压力

    \(\mathcal{Description}\)   Link.   给定一个 \(n\) 个点 \(m\) 条边的连通无向图,并给出 \(q\) 个点对 \((u,v)\),令 \(u\) 到 \ ...

  7. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  8. 关于连通性问题的Tarjan算法暂结

    关于基础知识的预备桥和割点.双联通分量.强连通分量,支配树.(并不会支配树) 关于有向图的Tarjan,是在熟悉不过的了,它的主要功能就是求强联通分量,缩个点,但是要注意一下构建新图的时候有可能出现重 ...

  9. Note -「圆方树」学习笔记

    目录 圆方树的定义 圆方树的构造 实现 细节 圆方树的运用 「BZOJ 3331」压力 「洛谷 P4320」道路相遇 「APIO 2018」「洛谷 P4630」铁人两项 「CF 487E」Touris ...

随机推荐

  1. hibernate hql语句 group by having 的坑

    我期望获得这个列表 然而,使用hql只能获得第一条数据,后来我琢磨了一下,和group by有关系 应该改成 成功查询到

  2. python学生管理系统

    import osimport re #获取本机用户名,构建student.txt文件名创建在左面import getpassusername=getpass.getuser()print(" ...

  3. 廖雪峰Python总结3

    1.模块简介 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件中,这样每个文件包含的代码相对来说就比较少.一个.py文件就称之为一个模块(Module). 使用模块的好处: 提高了代码的可 ...

  4. COOKIE与SESSION的详解

    cookie与session的小例子: 包含cookie记住登录名,session防止用户非法登录2个例子: 问我拿吧,这个下载连接挂了 描述 cookie过程描述 网站为了辨别用户身份.进行 ses ...

  5. Valgrind 初次接触

    Valgrind 英文的意思是:堆内存 它有很多小工具,作用各不相同 学习于: http://blog.csdn.net/sduliulun/article/details/7732906 http: ...

  6. laravel 分页带参数

    {{$data->appends(request()->except(['page']))->links()}}

  7. 【JZOJ4790】【NOIP2016提高A组模拟9.21】选数问题

    题目描述 在麦克雷的面前有N个数,以及一个R*C的矩阵.现在他的任务是从N个数中取出R*C个,并填入这个矩阵中.矩阵每一行的法值为本行最大值与最小值的差,而整个矩阵的法值为每一行的法值的最大值.现在, ...

  8. 使用cmd发送邮件

    转自:http://www.cnblogs.com/fanyong/p/3498670.html 本文演示用命令行发送邮件的过程. SMTP 首先介绍下smtp协议——简单邮件传输协议 (Simple ...

  9. 1.27eia原油

  10. PyCharm切换Python版本

    由于代码格式问题,很多情况下需要我们去切换Python版本,那么在当下火爆的PyCharm中是如何切换Python版本的呢? 打开File菜单,选择Settings: 打开Settings窗口后,选择 ...