首页 > 其他分享 >Luogu P3469 [POI2008]BLO-Blockade

Luogu P3469 [POI2008]BLO-Blockade

时间:2022-10-13 01:33:41浏览次数:71  
标签:连通 int Luogu tarjan Blockade BLO dfn low siz

[P3469 POI2008]BLO-Blockade - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

图 \(G\) 本身联通。删除 \(u\) 的连边后会形成 \(k \ge 2\) 个连通块(至少会把 \(u\) 隔离出来)。设这些连通块的大小是 \(s_1, \cdots s_k\),那么答案是 \(s_1 \times (n - s_1) + s_2 \times (n-s_2) + \cdots + s_k \times (n - s_k)\)。

在 \(G\) 上 tarjan。当前节点为 \(u\),删除 \(u\) 的连边后连通块有三种:

  • \(\{u\}\)(一个);
  • 在 \(u\) 在搜索树上的后代 \(v\) 中,满足 \(dfn[v] \ge low[u]\) 的,搜索树上以 \(v\) 为根的子树上的节点集(零个到多个);
  • 上面那两块除去之后剩余所有节点的集合(一个)。

只要在 tarjan 的时候统计就行了。

并不需要统计割点,但是确实运用了这个思想。

\(\mathcal{O}(n+m)\)。

/*
 * @Author: crab-in-the-northeast 
 * @Date: 2022-10-13 00:45:34 
 * @Last Modified by: crab-in-the-northeast
 * @Last Modified time: 2022-10-13 01:12:38
 */
#include <bits/stdc++.h>
#define int long long

inline int read() {
    int x = 0;
    bool flag = true;
    char ch = getchar();
    while (!isdigit(ch)) {
        if (ch == '-')
            flag = false;
        ch = getchar();
    }
    while (isdigit(ch)) {
        x = (x << 1) + (x << 3) + ch - '0';
        ch = getchar();
    }
    if(flag)
        return x;
    return ~(x - 1);
}

const int maxn = (int)1e5 + 5;

std :: vector <int> G[maxn];

int siz[maxn], low[maxn], dfn[maxn], ans[maxn], times;

int n;

inline bool gmi(int &a, int b) {
    return b < a ? a = b, true : false;
}

inline void tarjan(int u) {
    dfn[u] = low[u] = ++times;
    siz[u] = 1;
    
    ans[u] = n - 1; // 第一种连通块的贡献

    int tot = n - 1; // 第三种连通块的大小,为 n-第一种连通块的大小-第二种的
    // 这里先把第一种的减去(就是1),一会还会减掉第二种的

    for (int v : G[u]) {
        if (!dfn[v]) {
            tarjan(v);
            siz[u] += siz[v];
            gmi(low[u], low[v]);
            if (low[v] >= dfn[u]) {
                ans[u] += siz[v] * (n - siz[v]); // 第二种连通块
                tot -= siz[v]; // 第三种连通块大小减去第二种的
            }
        } else
            gmi(low[u], dfn[v]);
    }

    ans[u] += tot * (n - tot); // 第三种连通块
}

signed main() {
    n = read();
    int m = read();
    while (m--) {
        int u = read(), v = read();
        G[u].push_back(v);
        G[v].push_back(u);
    }

    tarjan(1);

    for (int u = 1; u <= n; ++u)
        printf("%lld\n", ans[u]);
    
    return 0;
}

标签:连通,int,Luogu,tarjan,Blockade,BLO,dfn,low,siz
From: https://www.cnblogs.com/crab-in-the-northeast/p/luogu-p3469.html

相关文章

  • PriorityBlockingQueue详解
    PriorityBlockingQueue介绍【1】PriorityBlockingQueue是一个无界的基于数组的优先级阻塞队列,数组的默认长度是11,也可以指定数组的长度,且可以无限的扩充,直到资源消耗......
  • ModStartBlog v5.9.0 新增组件特性,基础布局优化
    系统介绍ModStart是一个基于Laravel模块化极速开发框架。模块市场拥有丰富的功能应用,支持后台一键快速安装,让开发者能快的实现业务功能开发。系统完全开源,基于Apache2.......
  • LinkedBlockingDeque详解
    LinkedBlockingDeque介绍【1】LinkedBlockingDeque是一个基于链表实现的双向阻塞队列,默认情况下,该阻塞队列的大小为Integer.MAX_VALUE,可以看做无界队列,但也可以设置容......
  • 开源,跨平台免费C++ IDE ---Code::Block
     CodeBlock是一个免费,开源的C++IDE,它看上去有一个一致的外观,满足用户的需要,具有扩展性和可配置性。这个IDE有你需要的所有功能,并且它是跨平台的。另外,其具有插件框架......
  • LinkedBlockingQueue详解
    LinkedBlockingQueue介绍【1】LinkedBlockingQueue是一个基于链表实现的阻塞队列,默认情况下,该阻塞队列的大小为Integer.MAX_VALUE,由于这个数值特别大,所以LinkedBlock......
  • Luogu2167 Bill的挑战 - 容斥 - dp -
    题目链接:https://www.luogu.com.cn/problem/P2167题解:摘录一段描述容斥题目的话:本题中,关于容斥系数,可以先感性理解一下,严格证明可以用即除了自身,自身的超集都计算......
  • Luogu P6157 有趣的游戏(平衡树 + 树链剖分)
    有趣的游戏题目描述游戏在一棵大小为\(n\)的树上进行。其中每个点都有点权,第\(i\)个点的点权为\(w_i\)。每一次系统会给出一条链,小A可以从这条链上找出两个点权......
  • vue下载blob无法获取响应头里面的Content-Disposition来提取文件名 --导出完成代码
    exportClick(){//导出letpar={}downAxiosFile('/personnel/change/perUser/exportXls',par).then((res)=>{let{data}=res;......
  • Bitcoin-NG: A Scalable Blockchain Protocol
    Motivation由于比特币平均10分钟出一个块,每个块大小限制在1MB,所以每秒只能记录3~4个交易,导致比特币系统存在着的吞吐量低下和高延迟的问题。本文的主要目的就是通过提......
  • 《EPSANet: An Efficient Pyramid Squeeze Attention Block on Convolutional Neural
    论文题目:《EPSANet:AnEfficientPyramidSqueezeAttentionBlockonConvolutionalNeuralNetwork》 论文作者:HuZhang,KekeZu,JianLuetal.论文发表年份:2021.......