2019暑假集训 BLO
5 5
1 2
2 3
1 3
3 4
4 5
8
8
16
14
8
易得是割点板子题
对于图上每个割点(非割点无法对答案进行贡献)而言,设其将原连通图分为k个不相连通的子图,第i个子图元素个数为x[i],
于是该割点对答案的贡献为Σx[i]*x[j](i!=j,i,j∈x)。
同时观察样例我们可以知道,所谓不能互通的点具有顺序(比如(1,2)和(2,1))。
我们又知道,对于tarjan算法中一棵搜索树,一共包含两个部分:
(1)由割点引出的很多棵子树。
(2)与割点父亲相连通的所有点。
(3)割点本身。

其中绿、蓝、黄分别是第1、2、3部分。
为了方便起见,我们在下文中将这三部分用1、2和3表示。
所以我们可以将答案分成以下几个部分:
(1)搜索树上每棵由根节点引出的子树向其它点连通的点对(包括了1内部的点对、1向2连通的点对、1向3连通的点对)
(2)与割点父亲连通的点向割点连通的点对(2向3)
(3)割点向所有点连通的点对(3向1、2)
(4)与割点父亲连通的点向根节点子树连通的点对(2向1)
第一部分很容易处理,我们设每棵根节点prev向外引出的子树元素个数为subtree[prev],则其余点的个数共(n-subtree[prev])个,
于是我们可以将subtree[prev]*(n-subtree[prev])贡献到答案ans[x]中;(注意x是每个prev的父亲)
第二部分,我们设所有割点引出的子树(不包含割点自己)元素个数总和为sum,因为每次讨论的割点只有一个,其余点就有(n-sum-1)个,
则我们可以将(n-sum-1)贡献到答案ans[x]中;
第三部分更容易处理,因为每次讨论的割点只有一个,其它点有(n-1)个,于是我们将(n-1)贡献到答案中;
第四部分,我们将sum*(n-sum-1)贡献到答案中。
于是,对于每个割点x,有ans[x]=∑subtree[prev]*(n-subtree[prev])+(n-sum-1)+(n-1)+sum*(n-sum-1)=∑subtree[prev]*
(n-subtree[prev])+(n-sum-1)+(sum+1)*(n-sum-1);
对于非割点x,有ans[x]=2*(n-1)(只有割点本身受影响)。
关于统计subtree数组,我们每次进入函数时将subtree[x]置为1(表示这棵树只有根节点一个节点),然后在tarjan(y)回溯时令
tarjan[x]=tarjan[y]+1即可。
这种类似前缀和的树上技巧需要我们学习。
上代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int head[],num,n,m,cut[],dfn[],subtree[],low[],root,cnt;
long long ans[];
struct edge
{
int u,v,nxt;
}e[];
void add(int u,int v)
{
e[num].u=u,e[num].v=v;
e[num].nxt=head[u],head[u]=num++;
}
void tarjan(int x,int in_edge)/*这里用到一个技巧,对于每个点x记录上一个点搜索到x的边的编号,因为是无向图,则其反向边的编号必为in_edge^1(可以自己算一下),但需要注意邻接表必须从0开始存*/
{
dfn[x]=low[x]=++cnt;
subtree[x]=;
int flag=,sum=;
for(int st=head[x];st!=-;st=e[st].nxt)
{
int y=e[st].v;
if(!dfn[y])
{
tarjan(y,st);
subtree[x]+=subtree[y];
low[x]=min(low[x],low[y]);
if(low[y]>=dfn[x])
{
sum+=subtree[y];
ans[x]+=(long long)subtree[y]*(n-subtree[y]);//(1)
flag++;
if(x!=root||flag>)cut[x]=;
}
}
else if(st!=(in_edge^))//注意这个地方,异或运算的优先级低于比较,所以必须加括号
{
low[x]=min(low[x],dfn[y]);
}
}
if(cut[x]) {
ans[x]+=(long long)(n-sum-)*(sum+)+(n-);//(2)(3)(4)
}
else ans[x]=*(n-);//不是割点则不影响其它点
}
int main()
{
memset(head,-,sizeof head);
scanf("%d%d",&n,&m);
int a,b;
for(int i=;i<=m;i++)
{
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}//注意是无向图
root=;
for(int i=;i<=n;i++)//处理不连通图
if(!dfn[i])root=i,tarjan(i,-);
for(int i=;i<=n;i++)printf("%lld\n",ans[i]);//注意不开longlong会炸
return ;
}
2019暑假集训 BLO的更多相关文章
- 2019暑假集训 Intervals
题目描述 给定n个闭区间[ai,bi]和n个整数ci.你需要构造一个整数集合Z,使得对于任意i,Z中满足ai<=x<=bi的x不少于ci个.求Z集合中包含的元素个数的最小值. 输入 第一 ...
- 2019暑假集训 windy数
题目描述 Windy 定义了一种 Windy 数:不含前导零且相邻两个数字之差至少为2的正整数被称为 Windy 数. Windy 想知道,在A和B之间,包括A和B,总共有多少个 Windy 数? 输 ...
- 2015UESTC 暑假集训总结
day1: 考微观经济学去了…… day2: 一开始就看了看一道题目最短的B题,拍了半小时交了上去wa了 感觉自己一定是自己想错了,于是去拍大家都过的A题,十分钟拍完交上去就A了 然后B题写了一发暴力 ...
- STL 入门 (17 暑假集训第一周)
快速全排列的函数 头文件<algorithm> next_permutation(a,a+n) ---------------------------------------------- ...
- 暑假集训Day2 互不侵犯(状压dp)
这又是个状压dp (大型自闭现场) 题目大意: 在N*N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. ...
- 暑假集训Day1 整数划分
题目大意: 如何把一个正整数N(N长度<20)划分为M(M>=1)个部分,使这M个部分的乘积最大.N.M从键盘输入,输出最大值及一种划分方式. 输入格式: 第一行一个正整数T(T<= ...
- 2013ACM暑假集训总结-致将走上大三征途的我
回想起这个暑假,从开始与雄鹰一起的纠结要不要进集训队,与吉吉博博组队参加地大邀请赛,害怕进不了集训队.当时激励我月份开始接触的,记得当时在弄运动会来着,然后就问了雄鹰一些输入输出的东西,怀着满心的期待 ...
- [补档]暑假集训D5总结
%dalao 今天又有dalao来讲课,讲的是网络流 网络流--从入门到放弃:7-29dalao讲课笔记--https://hzoi-mafia.github.io/2017/07/29/27/ ...
- [补档]暑假集训D1总结
归来 今天就这样回来了,虽然心里极其不想回来(暑假!@#的只有一天啊喂),但还是回来了,没办法,虽然不喜欢这个地方,但是机房却也是少数能给我安慰的地方,心再累,也没有办法了,不如好好集训= = %da ...
随机推荐
- Windows 上静态编译 Libevent 2.0.10 并实现一个简单 HTTP 服务器(图文并茂,还有实例下载)
[文章作者:张宴 本文版本:v1.0 最后修改:2011.03.30 转载请注明原文链接:http://blog.s135.com/libevent_windows/] 本文介绍了如何在 Window ...
- 附005.Kubernetes身份认证
一 Kubernetes访问 1.1 Kubernetes交互 与Kubernetes交互通常有kubectl.客户端(Dashboard).REST API请求. 1.2 API访问流程 用户使用k ...
- 【转载】JDK自带的log工具
版权声明:本文为Jaiky_杰哥原创,转载请注明出处.This blog is written by Jaiky, reproduced please indicate. https://blog.c ...
- 【hibernate-validator+SpringMVC】后台参数校验框架
hibernate-validator+SpringMVC 简介:简单说,就是对Entity进行校验. 1.导包,没有很严谨的对应关系,所以我用了比较新的版本,支持更多的注解. <depende ...
- 使用 cxf的程序 在win10 测试部署时报空指针异常
2018-11-08 15:50:55.072 DEBUG 21524 --- [nio-8080-exec-1] o.s.b.w.s.f.OrderedRequestContextFilter : ...
- asp.net core系列 67 Web压力测试工具WCAT
一.介绍 最近搭建了一套CQRS框架,需要在投入开发前,进行必要的压力测试.Web Capacity Analysis Tool (Wcat)是一种轻量级HTTP负载生成工具,主要用于衡量受控环境中 ...
- 分布式事务(2)---TCC理论
分布式事务(2)---TCC理论 上篇讲过有关2PC和3PC理论知识,博客:分布式事务(1)---2PC和3PC理论 我的理解:2PC.3PC还有TCC都蛮相似的.3PC大致是把2PC的第一阶段拆分成 ...
- python数据库-MySQL与python的交互
一.python3中安装PyMySQL模块 命令安装: sudo apt-get install python-mysql 或者 pip install pymysql 2.使用在pyCharm中安装 ...
- InnoDB存储引擎--学习笔记-redo log
目录 1. 引言 2. 重做日志文件和相关概念介绍 + 2.1. 重做日志文件和bin log + 2.2. LSN(log squence number) 3. 重做日志文件基本工作原理 4. 重做 ...
- 深入学习Spring框架(二)- 注解配置
1.为什么要学习Spring的注解配置? 基于注解配置的方式也已经逐渐代替xml.所以我们必须要掌握使用注解的方式配置Spring. 关于实际的开发中到底使用xml还是注解,每家公司有着不同的使用习惯 ...