zoukankan      html  css  js  c++  java
  • [Luogu] P3469 [POI2008]BLO-Blockade

    Description

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

    Solution

    注意到如果一个点不是割点,那么它的答案肯定是(2(n-1))(无序点对)

    而如果它是割点,那么封锁它后,即把这个点抠出来后,原来的图一定被分成了若干部分。对于每个部分,设它的节点个数为(t),那么它对答案造成的贡献为(t*(n-t)),因为这(t)个点到其他任意(n-t)个点都到不了。

    现在我们来思考如何算出这些部分的节点个数。其实很简单。首先节点(x)自身构成一个大小为(1)的部分。然后对于每个满足(dfn[x]le{low[y]})的节点(y),大小是(sz[y])。最后可能还有一个部分,由除了上述节点之外的所有节点构成,大小为(n-1-sum_{y=1}^tsz[y])

    注意要开(long long)

    Code

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define ll long long
    
    int n, m, tot, ind, rt, sz[100005], cut[100005], hd[100005], to[1000005], nxt[1000005], low[100005], dfn[100005];
    
    ll res[100005];
    
    int read()
    {
    	int x = 0, fl = 1; char ch = getchar();
    	while (ch < '0' || ch > '9') { if (ch == '-') fl = -1; ch = getchar();}
    	while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    	return x * fl;
    }
    
    void add(int u, int v)
    {
    	tot ++ ;
    	to[tot] = v;
    	nxt[tot] = hd[u];
    	hd[u] = tot;
    	return;
    }
    
    void Tarjan(int x)
    {
    	low[x] = dfn[x] = ++ ind;
    	int t = 0, sum = 0;
    	sz[x] = 1;
    	for (int i = hd[x]; i; i = nxt[i])
    	{
    		int y = to[i];
    		if (!dfn[y])
    		{
    			Tarjan(y);
    			sz[x] += sz[y];
    			low[x] = min(low[x], low[y]);
    			if (low[y] >= dfn[x])
    			{
    				t ++ ;
    				if (x != rt || t > 1) cut[x] = 1;
    				if (cut[x]) res[x] += 1ll * sz[y] * (n - sz[y]), sum += sz[y];
    			}
    		}
    		else low[x] = min(low[x], dfn[y]);
    	}
    	if (cut[x]) res[x] += 1ll * (n - 1) + 1ll * (n - 1 - sum) * (sum + 1);
    	else res[x] = 2ll * (n - 1);
    	return;
    }
    
    int main()
    {
    	n = read(); m = read();
    	for (int i = 1; i <= m; ++ i)
    	{
    		int u = read(), v = read();
    		add(u, v); add(v, u);
    	}
    	rt = 1, Tarjan(1);
    	for (int i = 1; i <= n; i ++ )
    		printf("%lld
    ", res[i]);
    	return 0;
    }
    
  • 相关阅读:
    【JDBC】JDBC实战
    【JDBC】JDBC操作实战
    【Oracle】事务、表复制
    Hibernate 再接触 继承映射
    Hibernate 再接触 集合映射
    Hibernate 再接触 CRUD
    Hibernate 再接触 多对多单向双向关联
    Hibernnate 一对多多对一双向关联
    Hibernate 再接触 一对多单向关联
    Hibernate 再接触 多对一与一对多
  • 原文地址:https://www.cnblogs.com/andysj/p/13914070.html
Copyright © 2011-2022 走看看