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 ...
随机推荐
- 关于跨进程使用回调函数的研究:以跨进程获取Richedit中RTF流为例(在Delphi 初始化每一个TWinControl 对象时,将会在窗体 的属性(PropData)中加入一些标志,DLL的HInstance的值与HOST 进程的HInstance并不一致)
建议先参考我上次写的博文跨进程获取Richedit中Text: 获得QQ聊天输入框中的内容 拿到这个问题,我习惯性地会从VCL内核开始分析.找到TRichEdit声明的单元,分析TRichEdit保存 ...
- Wp8 Popup不随输入法偏移问题解决方案
在wp中我们经常要实现,浮窗的效果这时我们就会考虑到Popup,但是在用Popup开发我们会遇到一个非常尴尬的问题,由于Popup不在主界面的可视化树内,在Popup显示的位置在输入法面板出现的范围时 ...
- Qt之QGraphicsEffect阴影、模糊效果
Qt之QGraphicsEffect阴影.模糊效果 Qt之QGraphicsEffect阴影模糊效果 效果图 阴影和模糊效果 正常效果 代码 customshadoweffecth customsha ...
- poi 操作Excel 以及大数据量导出
maven 依赖 (版本必须一致,否则使用SXSSFworkbook 时程序会报错) <dependency> <groupId>org.apache.poi</grou ...
- Django预备知识
http协议 url: 协议://域名(IP)+端口(80)/路径?参数(a=1&b=2) 示例:https://www.baidu.com/s/?wd=aaa MVC M:mdoel 与数据 ...
- 每日一问:到底为什么属性动画后 View 在新位置还能响应事件
在 Android 开发中,我们难免会使用动画来处理各种各样的动画效果,以满足 UI 的高逼格设计.对于比较复杂的动画效果,我们通常会采用著名的开源库:lottie-android,或许你会对 lot ...
- lodop+art-template实现web端漂亮的小票样式打印
一. 现状 由于之前采用Lodop打印控件(商业版付费,可以使用免费版 但是会有水印)去打印小票,是一行一行的打印,但是不满足UI给到复杂布局的小票样式,所以得重新考虑如何来实现. 二. 介绍 art ...
- 浅入深出Vue:事件处理
上一篇的最后留下了一个 v-on的思考,也就是本章的主题:事件处理 为什么需要事件处理 在前端开发中,经常要面对各种表单.按钮.而这里面就住着一个事件:点击 (click). 前端童鞋们肯定不陌生它, ...
- css之vw布局
vw,vh是视口单位,是相对视口单位,与百分百布局不一样的是,百分百是相对于父及元素,而vw布局是相对与窗口. 而rem布局是要与js一起配合 // 以iphone6设计稿 @function px2 ...
- auth-booster配置和使用(yii1.5)
auth-booster这个是一个yii框架扩展中的一个模块.是非常好用的(但是里面的说明都是英文的,所以国人用还需要改一点里面的汉化) 1.下载auth-booster这个:http://www.y ...