【dfs+连通分量】Bzoj1123 POI2008 BLO

Description

Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 所有towns连通。

Input

输入n<=100000 m<=500000及m条边

Output

输出n个数,代表如果把第i个点去掉,将有多少对点不能互通。

Solution

求割顶的一系列操作不仅可以用来求割顶,也可以解决很多问题,比如这道题。

dfs是很神奇的,对于节点u能扩展出去的v的子树是互相独立的,反向边也只会往上连。

那么对于u,他的父亲p和能连回去的v形成一个连通块,其余v各成一个连通块。

然后就很好统计了(细节自己想),其实用dfs树来处理大概就是树形dp。

Code

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define ll long long
 4 using namespace std;
 5 const int maxn=1e5+5,maxm=1e6+5;
 6
 7 int pre[maxn],low[maxn],clock;
 8 int head[maxn],e[maxm],nxt[maxm],cnt;
 9 int adde(int u,int v){
10     e[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;
11     e[++cnt]=u;nxt[cnt]=head[v];head[v]=cnt;
12 }
13 ll ans[maxn],t[maxn];
14 int n,m,size[maxn];
15
16 int dfs(int u){
17     pre[u]=low[u]=++clock;
18     size[u]=1;
19     for(int i=head[u];i;i=nxt[i]){
20         int v=e[i];
21         if(pre[v]) low[u]=min(low[u],pre[v]);
22         else{
23             dfs(v);
24             size[u]+=size[v];
25             low[u]=min(low[u],low[v]);
26             if(low[v]>=pre[u]){
27                 ans[u]+=t[u]*size[v];
28                 t[u]+=size[v];
29             }
30         }
31     }
32     ans[u]+=t[u]*(n-t[u]-1);
33     ans[u]=(ans[u]+n-1)*2;
34 }
35
36 int main(){
37     scanf("%d%d",&n,&m);
38     int u,v;
39     for(int i=1;i<=m;i++){
40         scanf("%d%d",&u,&v);
41         adde(u,v);
42     }
43
44     for(int i=1;i<=n;i++)
45         if(!pre[i]) dfs(i);
46
47     for(int i=1;i<=n;i++)
48         printf("%lld\n",ans[i]);
49     return 0;
50 }

时间: 2024-08-04 07:09:18

【dfs+连通分量】Bzoj1123 POI2008 BLO的相关文章

BZOJ1123: [POI2008]BLO

1123: [POI2008]BLO Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 614  Solved: 235[Submit][Status] Description Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 所有towns连通. Input 输入n<=100000 m<=500000及m条边 Output 输出n个数,代表如果把第i个点去掉,将有多

bzoj1123: [POI2008]BLO(割点)

bzoj1123 题目描述:给定n个城市,m条边,每条边连接两个不同的城市,没有重复的路,所有的城市相连. 输入格式:输入n<=100000 m<=500000 及 m 条边 输出格式:输出 n 个数,代表如果把第 i 个点去掉,将有多少对点不能互通. 输入样例: 5 5 1 2 2 3 1 3 3 4 4 5 输出样例: 8 8 16 14 8 解析:把每个点去掉,对答案的贡献就是每个被分割出的联通块的的大小之积 + (n - 1) 再乘2 ???关键在于如何快速求出每个联通块的大小. ??

【BZOJ-1123】BLO Tarjan 点双连通分量

1123: [POI2008]BLO Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 970  Solved: 408[Submit][Status][Discuss] Description Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 所有towns连通. Input 输入n<=100000 m<=500000及m条边 Output 输出n个数,代表如果把第

[POI2008]BLO

1123: [POI2008]BLO Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1519  Solved: 697[Submit][Status][Discuss] Description Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 所有towns连通. Input 输入n<=100000 m<=500000及m条边 Output 输出n个数,代表如果把

BZOJ 1123: [POI2008]BLO

1123: [POI2008]BLO Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1030  Solved: 440[Submit][Status][Discuss] Description Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 所有towns连通. Input 输入n<=100000 m<=500000及m条边 Output 输出n个数,代表如果把

1123: [POI2008]BLO

1123: [POI2008]BLO Time Limit: 10 Sec  Memory Limit: 162 MB链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1123 Description Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 所有towns连通. Input 输入n<=100000 m<=500000及m条边 Output 输出n个数

【搭楼】大力开刷图论

写在前面 继前半个月的刷杂题后,学OI的感觉找到了些,于是来刷专题吧! 感觉我接触图论到现在也有一个学期了,然而感觉我还没有系统地搞过图论或者说我是一个图论还没有入门的人>.< 刷图论主要做三件事: ①大白大白: ②BzojBzoj: ③紫书的习题: 我理想的进度安排是: 6.4-6.10搞完除网络流部分,然后开刷网络流,因为现在还没有开始网络流也不知道是什么情况. 知识刷的顺序就按照大白的来. 图的连通 ——DFS遍历,割顶,桥,双连通分量,强连通分量 DFS遍历 DFS的神奇之处是什么呢,

tarjan

首先还是说明这是一个坑 然后tarjan以前一直处于懵懵懂懂的状态,决定痛改前非好好学. tarjan可以用来求强联通分离. 它有两个数组,一个是dfn,一个是low. 定义DFN(u)为节点u搜索的次序编号(时间戳).Low(u)为u或者u的子树能够追溯到的最早的栈中的节点的次序号. 然后就发现u的儿子无非三种情况:一是还没访问过,然后是访问过而且已经在某个强联通分量里面,最好是访问过但是还在栈里面. 对于第一种情况就直接访问 然后low[u]=min(low[u],low[son]) 对于第

图论算法之DFS与BFS

概述(总) DFS是算法中图论部分中最基本的算法之一.对于算法入门者而言,这是一个必须掌握的基本算法.它的算法思想可以运用在很多地方,利用它可以解决很多实际问题,但是深入掌握其原理是我们灵活运用它的关键所在. 含义特点 DFS即深度优先搜索,有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解,那就返回到上一个节点,然后从另一条路开始走到底,这种尽量往深处走的概念即是深度优先的概念. 由于用到递归,当节点特别多且深度很大