题面

传送门:https://www.luogu.org/problemnew/show/P3469


Solution

先跟我大声念:

poi!


然后开始干正事。

首先,我们先把题目中的点分为两类:去除这个点能把图分为几个部分的,去除这个点不影响整个图的连通性的

如下图:

点上的数字表示这个点的搜索序。

我们称这些对连通性有影响的点为割点

先假设我们能求出这些点以及其出去后把图分为几块之后那几块分别的大小。

是不是发现了什么?

对于非割点,答案显然是2*(n-1) (因为它不能影响别的点对连通性,能影响的只是别人到它以及它到别人)

对于割点,它把那几块弄得无法联通,即那几块中不同块的两个点肯定就无法联通了,答案也就是每组块的点的数量互相乘出来,再加上2*(n-1)。

接下来就是如何求割点了。

这时候我们又得请出伟大的Tarjan了。

先回忆一下求强连通分块的做法,我们这里求割点的做法与其类似。

但有以下几点不同:

1.我们在求low的时候不用讨论所连向的点是否在栈中了,因为无向图中没有横插边的说法(但是要记录当前的父亲,防止我们的low直接计算回去)

2.当一个点的某一个孩子的low>=此点的dfn时,说明这个点就是割点。因为孩子的low大于当前节点的dfn,说明它没有办法直接从当前节点回到搜索树搜过的节点。如果当前节点删除了,此孩子将会分割开来)

至于怎么求每个孩子的size........

(我想这个应该不用说了吧)

就是搜的时候加上去就好,如果不清楚的话看一下代码就懂了。

时间复杂度O(n)

完全OjbK


Code

//Luogu P3469 [POI2008]BLO-Blockade
//June,11th,2018
//玄幻割点
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
long long read()
{
long long x=0,f=1; char c=getchar();
while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
const int N=100000+100;
vector <long long> e[N],nd_size[N];
int n,m;
int dfn[N],low[N],IsGD[N],nd_to,size[N];
void Tarjan(int now,int fa)
{
dfn[now]=low[now]=++nd_to;
size[now]++;
int temp=0;
for(int i=0;i<int(e[now].size());i++)
if(dfn[e[now][i]]==0)
{
Tarjan(e[now][i],now);
size[now]+=size[e[now][i]];
low[now]=min(low[now],low[e[now][i]]);
if(low[e[now][i]]>=dfn[now])
{
temp+=size[e[now][i]];
IsGD[now]=true;
nd_size[now].push_back(size[e[now][i]]);
}
}
else if(e[now][i]!=fa)
low[now]=min(low[now],low[e[now][i]]);
if(IsGD[now]==true and n-temp-1!=0)
nd_size[now].push_back(n-temp-1);
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++)
{
e[i].reserve(4);
nd_size[i].reserve(4);
}
for(int i=1;i<=m;i++)
{
int s=read(),t=read();
e[s].push_back(t);
e[t].push_back(s);
} Tarjan(1,0); for(int i=1;i<=n;i++)
{
long long ans=2*(n-1);
if(nd_size[i].size()!=0 and nd_size[i].size()!=1)
{
for(int j=0;j<int(nd_size[i].size());j++)
for(int k=j+1;k<int(nd_size[i].size());k++)
ans+=2*nd_size[i][j]*nd_size[i][k];
}
printf("%lld\n",ans);
}
return 0;
}

正解(C++)

[Luogu P3469] [POI2008]BLO-Blockade (割点)的更多相关文章

  1. P3469 [POI2008]BLO-Blockade(Tarjan 割点)

    P3469 [POI2008]BLO-Blockade 题意翻译 在Byteotia有n个城镇. 一些城镇之间由无向边连接. 在城镇外没有十字路口,尽管可能有桥,隧道或者高架公路(反正不考虑这些).每 ...

  2. 割点判断+luogu 3469 POI2008 BLO

    1.根节点,有2棵及以上子树 2.非根节点,有子节点dfn[u]<=low[v] #include <bits/stdc++.h> #define N 1000050 using n ...

  3. BZOJ 1123 && Luogu P3469 [POI2008]BLO-Blockade 割点+乘法原理

    想了半天式子...最后在邓大师的帮助下想出此题....QWQ我还是太菜了 对于一个非割点,ans+=2*(n-1); 对于一个割点,ans+= #include<cstdio> #incl ...

  4. [LUOGU] P3469 [POI2008]BLO-Blockade

    https://www.luogu.org/problemnew/show/P3469 求无向图分别删去每个点后不连通的点对数. 首先,对于任何一个点,它本身删了,就会和剩下的n-1个点不连通,点对是 ...

  5. 【luogu P3469 [POI2008]BLO-Blockade】 题解

    题目链接:https://www.luogu.org/problemnew/show/P3469 #include <cstdio> #include <cstring> #i ...

  6. bzoj1123 [POI2008]BLO——求割点子树相乘

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1123 思路倒是有的,不就是个乘法原理吗,可是不会写...代码能力... 写了一堆麻麻烦烦乱七 ...

  7. BZOJ 1123: [POI2008]BLO 求割点_乘法原理_计数

    Description Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 所有towns连通. Input 输入n&l ...

  8. 洛谷 P3469 [POI2008]BLO-Blockade (Tarjan,割点)

    P3469 [POI2008]BLO-Blockade https://www.luogu.org/problem/P3469 题目描述 There are exactly nn towns in B ...

  9. bzoj 1123 [POI2008]BLO Tarjan求割点

    [POI2008]BLO Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1540  Solved: 711[Submit][Status][Discu ...

随机推荐

  1. Prime Path(POJ - 3126)【BFS+筛素数】

    Prime Path(POJ - 3126) 题目链接 算法 BFS+筛素数打表 1.题目主要就是给定你两个四位数的质数a,b,让你计算从a变到b共最小需要多少步.要求每次只能变1位,并且变1位后仍然 ...

  2. matlab中repmat函数的用法

    转载:https://blog.csdn.net/facetosea1/article/details/83573859 B = repmat(A,m,n)B = repmat(A,[m n])B = ...

  3. python 给IDLE添加行号

    [LineNumbers] enable=1 enable_editor=1 enable_shell=1 visible=1 [LineNumbers_cfgBindings] linenumber ...

  4. PJzhang:鸟哥的linux私房菜-shell脚本-上

    猫宁~~~ 建议全程在centos7中进行,我在kali linux中有些命令无法执行. 1~家目录下创建bin文件,test.sh文件在bin目录 下面的shell代码打印Hello World! ...

  5. Java源码详解系列(十一)--Spring的使用和源码

    Spring 是一个一站式的 Java 框架,致力于提高我们项目开发的效率.通过 Spring,我们可以避免编写大量额外代码,更专注于我们的核心逻辑.目前,Spring 已经成为最受欢迎的 Java ...

  6. ie 版本判断脚本

    // 获取IE版本 /** * @return {string} */ function IEVersion() { // 取得浏览器的userAgent字符串 var userAgent = nav ...

  7. 用redis当作LRU缓存

    原文地址:https://redis.io/topics/lru-cache Redis可以用来作缓存,他可以很方便的淘汰(删除)旧数据添加新数据,类似memcached.LRU只是其中的一种置换算法 ...

  8. 多测师讲解接口测试 _理论基础知识001_高级讲师肖sir

    前言: 我们今天进入接口测试的学习! 今天学习的内容是偏向理论 接口理论 了解接口测试(1) 一.什么是接口测试? 接口统称api,即程序与程序之间的对接.交接.交互.是测试系统组件间接口的一种测试. ...

  9. 多测师讲解html _段落标签002_高级讲师肖sir

    <html> <head> <meta charset="UTF-8"> <title>段落标签</title> < ...

  10. 详解command设计模式,解耦操作和回滚

    大家好,欢迎来到设计模式专题,我们的主旨是介绍一些有趣好玩的设计模式. 今天我们介绍的设计模式叫做命令模式(command),在这个模式下,我们可以实现do和undo的解耦,让使用方不用关心内部的实现 ...