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 ...
随机推荐
- 记住以下10条,Linux磁盘与文件系统管理无忧矣
1.查看当前Linux系统所支持的文件系统:ls -l /lib/modules/$(uname -r)/kernel/fs:目前已加载到内存中支持的文件系统:cat /proc/filesystem ...
- modelform组件以及ChoiceField属性
一. Forms组件补充 1.__init__() 如果继承forms.Form的类中的每一个字段,或者大部分字段都做了相同的约束,可以将该约束放到__init__中编写 实例:每一个字段都需要添加f ...
- mysql-5.7.24-winx64安装与Navicat_for_MySQL_10.1.7注册码
mysql安装图解:https://blog.csdn.net/qq_38455201/article/details/83419450 Navicat注册码名:组织:注册码:均为NAVN-LNXG- ...
- 05-MySQL的完整性约束
1.整体说明(1)讨论重点内容 not null 与default unique:表中该值唯一,不能有重复值 primary auto_increment foreign ...
- 【maven 】jar包冲突-记一次冲突解决
方法一:根据mvn提示一个一个排除 1.请到pom.xml文件所在的目录(包含父子目录)下分别执行下面的命令排查是什么原因导致fastjson版本不正确: mvn dependency:tree -D ...
- 前端摸爬滚打之路(一)之 JavaScript 基础
前言:这是我第一次在博客上记录自己的前端学习过程,以往都是在桌面右侧开个 onenote 小窗,记录自己在学习过程中获得的知识.通常都是记录的满满当当,然后心满意足的关闭窗口,但是记录不代表学会.这些 ...
- Appium+python自动化(十五)- Android 这些基础知识,你知多少???(超详解)
简介 前边具体操作和实战已经讲解和分享了很多了,但是一些android的一些基础知识,你又知道多少了,你都掌握了吗?这篇就由宏哥给小伙伴们既是一个分享,又是对前边的一次总结.为什么要对这些做一个简单的 ...
- Linux 运行jar包命令(Cent OS 7后台运行jar包)
Linux 运行jar包命令如下: 方式一 特点:当前ssh窗口被锁定,可按CTRL + C打断程序运行,或直接关闭窗口,程序退出 那如何让窗口不锁定? 方式二 java -jar shareniu. ...
- 详解FIX协议的原理、消息格式及配置开发
一.定义 FIX协议是由国际FIX协会组织提供的一个开放式协议,目的是推动国际贸易电子化的进程,在各类参与者之间,包括投资经理.经纪人,买方.卖方建立起实时的电子化通讯协议.FIX协议的目标是把各类证 ...
- 安装Eclipse for MAC 苹果版
1. 安装Eclipse for MAC 苹果版 2. Thank you for downloading Eclipse If the download doesn't start in a few ...