题目描述
Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 所有towns连通。
输入
输入n<=100000 m<=500000及m条边
输出
输出n个数,代表如果把第i个点去掉,将有多少对点不能互通。
样例输入
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的更多相关文章

  1. 2019暑假集训 Intervals

    题目描述 给定n个闭区间[ai,bi]和n个整数ci.你需要构造一个整数集合Z,使得对于任意i,Z中满足ai<=x<=bi的x不少于ci个.求Z集合中包含的元素个数的最小值.  输入 第一 ...

  2. 2019暑假集训 windy数

    题目描述 Windy 定义了一种 Windy 数:不含前导零且相邻两个数字之差至少为2的正整数被称为 Windy 数. Windy 想知道,在A和B之间,包括A和B,总共有多少个 Windy 数? 输 ...

  3. 2015UESTC 暑假集训总结

    day1: 考微观经济学去了…… day2: 一开始就看了看一道题目最短的B题,拍了半小时交了上去wa了 感觉自己一定是自己想错了,于是去拍大家都过的A题,十分钟拍完交上去就A了 然后B题写了一发暴力 ...

  4. STL 入门 (17 暑假集训第一周)

    快速全排列的函数 头文件<algorithm> next_permutation(a,a+n) ---------------------------------------------- ...

  5. 暑假集训Day2 互不侵犯(状压dp)

    这又是个状压dp (大型自闭现场) 题目大意: 在N*N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. ...

  6. 暑假集训Day1 整数划分

    题目大意: 如何把一个正整数N(N长度<20)划分为M(M>=1)个部分,使这M个部分的乘积最大.N.M从键盘输入,输出最大值及一种划分方式. 输入格式: 第一行一个正整数T(T<= ...

  7. 2013ACM暑假集训总结-致将走上大三征途的我

    回想起这个暑假,从开始与雄鹰一起的纠结要不要进集训队,与吉吉博博组队参加地大邀请赛,害怕进不了集训队.当时激励我月份开始接触的,记得当时在弄运动会来着,然后就问了雄鹰一些输入输出的东西,怀着满心的期待 ...

  8. [补档]暑假集训D5总结

    %dalao 今天又有dalao来讲课,讲的是网络流 网络流--从入门到放弃:7-29dalao讲课笔记--https://hzoi-mafia.github.io/2017/07/29/27/   ...

  9. [补档]暑假集训D1总结

    归来 今天就这样回来了,虽然心里极其不想回来(暑假!@#的只有一天啊喂),但还是回来了,没办法,虽然不喜欢这个地方,但是机房却也是少数能给我安慰的地方,心再累,也没有办法了,不如好好集训= = %da ...

随机推荐

  1. CSS3 Maker提供了10个最为常用的CSS3属性在线生成工具

    CSS3 Maker提供了10个最为常用的CSS3属性在线生成工具,比如说border-radius.gradient.transfrom.animation.transition.rgba.text ...

  2. 用了WS_EX_LAYERED 后所有Twincontrl的wm_paint消息会停止(官方Layered Windows文档很多内容)good

    fmx 和 vcl 不一样, fmx 的阴影可以通过2D显示出来. VCL 无标题栏窗口的阴影很麻烦 280425268 我也是用两个窗口做阴影,并重绘了非客户区,不过阴影是基础自TwinContro ...

  3. IIS上.net注册

    如果先安装了.Net平台,后再安装IIS,那么在IIS中可能就没有出现ASP.NET版本的下拉菜单,这是我们可手动注册.Net 一般.Net版本都存放在:C:\WINDOWS\Microsoft.NE ...

  4. SYN3305A型 小型时统设备

       SYN3305A型  小型时统设备 产品概述 SYN3305A型小型时统设备是由西安同步电子科技有限公司精心设计.自行研发生产的一款高准确度的锁相石英频率标准.内装OCX0恒温晶体振荡器,利用G ...

  5. 分享android ADT百度云盘下载地址

    由于android官网经常无法打开,特意把最新的android ADT和SDK放到了百度云盘进行了分享,目录中包含Windows和Macbook两种平台的版本,请自行选择: http://pan.ba ...

  6. Tido 习题-二叉树-树状数组求逆序对

    这里给大家提供一个全新的求逆序对的方法 是通过树状数组来实现的 题目描述   样例输入 Copy 5 2 3 1 5 4 样例输出 Copy 3 提示     #include<iostream ...

  7. Spring_two

    Spring_two 基于注解的IOC配置 准备工作(参考上一篇) ); 接口的实现类AccountDaoImpl.java修改 /** * 账户的持久层实现类 */ @Repository(&quo ...

  8. 最全java多线程总结2--如何进行线程同步

      上篇对线程的一些基础知识做了总结,本篇来对多线程编程中最重要,也是最麻烦的一个部分--同步,来做个总结.   创建线程并不难,难的是如何让多个线程能够良好的协作运行,大部分需要多线程处理的事情都不 ...

  9. 利用Settings.bundle切换网络环境

    目的:一次性打包,测试可以去iPhone设置,找到APP,点击后然后可以自主切换网络环境(测试.预生产.正式).关闭APP重新打开生效. 撸起袖子加油干…… 1.生成并设置Setting.bundle ...

  10. Spring+Redis配置

    既上次把同事屁屁龙的tomcat数据源文档摘抄过来之后,这次获得其同意后,再次怀着感激涕零的心情,抄个爽. 全文非本人所写,所以若转载时,请标明文章来源于本人原创(不要脸真爽哈哈哈哈),谢谢! 1.j ...