zoukankan      html  css  js  c++  java
  • 「Luogu P3469」「POI2008」Blockade

    Description

    给定一张无向图,求每个点被封锁之后有多少个有序点对 ((x,y)(x e y,1le x,yle n)) 满足 (x) 无法到达 (y)

    Hint

    • (1le nle 10^5)
    • (1le mle 5 imes 10^5)

    Solution

    对第 (i) 个点分类讨论——如果 (i):

    1. 是割点:

      • Tarjan 算法是一个搜索树的 DFS,设 ( ext{size}_i) 为当前结点的第 (i) 个子树的大小(结点数),共有 (k) 个子树,那么删去这个割点的答案即为:
        (left[sum_{i = 1}^k ext{size}_i imes (n - ext{size}_i - 1) ight] + ext{sum} imes (n - ext{sum} - 1) + 2(n - 1))
      • 其中,( ext{sum} = sum_{i = 1}^k ext{size}_i),这些都可以在 Tarjan 算法中完成。
    2. 不是割点:

      • 很显然,其他的结点之间的连通性并不会受此影响,所以只是所以的有关于这一个点的点对没了,答案为 (2(n - 1))

    复杂度 (O(n + m))

    Code

    /*
     * Author : _Wallace_
     * Source : https://www.cnblogs.com/-Wallace-/
     * Problem : Luogu P3469 POI2008 Blockade
     */
    #include <algorithm>
    #include <cstdio>
    #include <vector>
    
    using namespace std;
    const int N = 1e6 + 5;
    
    vector<int> G[N];
    int n, m;
    
    int timer = 0;
    int dfn[N], low[N];
    bool cut[N];
    int size[N];
    long long ans[N];
    void Tarjan(int x) {
    	dfn[x] = low[x] = ++timer, size[x] = 1;
    	int ch = 0, sum = 0;
    	for (auto y : G[x]) {
    		if (!dfn[y]) {
    			Tarjan(y), size[x] += size[y];
    			low[x] = min(low[x], low[y]);
    			if (low[y] >= dfn[x]) {
    				ans[x] += size[y] * 1LL * (n - size[y] - 1);
    				sum += size[y], ++ch;
    				if (x != 1 || ch > 1) cut[x] = true;
    			}
    		}
    		low[x] = min(low[x], dfn[y]);
    	}
    	if (!cut[x]) ans[x] = (n - 1) * 2;
    	else ans[x] += (n - sum - 1) * 1LL * sum + (n - 1) * 2;
    }
    
    signed main() {
    	scanf("%d%d", &n, &m);
    	for (register int i = 1, u, v; i <= m; i++) {
    		scanf("%d%d", &u, &v);
    		G[u].push_back(v);
    		G[v].push_back(u);
    	}
    	
    	Tarjan(1);
    	
    	for (register int i = 1; i <= n; i++)
    		printf("%lld
    ", ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    拷贝构造函数与赋值函数的区别
    C++模板(一)
    拷贝构造函数
    memcpy函数
    malloc calloc 和 realloc
    extern关键字
    C中不安全函数
    缓冲区溢出问题
    C++引用
    背包问题专栏(01,完全,多重)
  • 原文地址:https://www.cnblogs.com/-Wallace-/p/12830460.html
Copyright © 2011-2022 走看看