[POI2008]BLO-Blockade【Tarjan缩点 圆方树】

题目链接

  有N个点,M条边组成的无向图,现在我们想知道删除一个点u,它会使得哪些x、y对,不能从x到达y,求对于每个点这样的<x,y>对的个数。

  于是,很明显的就是,我们可以将它缩点成为一个广义圆方树,然后在树上跑就是了。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cmath>
  4 #include <string>
  5 #include <cstring>
  6 #include <algorithm>
  7 #include <limits>
  8 #include <vector>
  9 #include <stack>
 10 #include <queue>
 11 #include <set>
 12 #include <map>
 13 #include <bitset>
 14 #include <unordered_map>
 15 #include <unordered_set>
 16 #define lowbit(x) ( x&(-x) )
 17 #define pi 3.141592653589793
 18 #define e 2.718281828459045
 19 #define INF 0x3f3f3f3f
 20 #define HalF (l + r)>>1
 21 #define lsn rt<<1
 22 #define rsn rt<<1|1
 23 #define Lson lsn, l, mid
 24 #define Rson rsn, mid+1, r
 25 #define QL Lson, ql, qr
 26 #define QR Rson, ql, qr
 27 #define myself rt, l, r
 28 #define pii pair<int, int>
 29 #define MP(a, b) make_pair(a, b)
 30 using namespace std;
 31 typedef unsigned long long ull;
 32 typedef unsigned int uit;
 33 typedef long long ll;
 34 const int maxN = 1e5 + 7, maxM = 1e6 + 7;
 35 int N, M, head[maxN], cnt;
 36 struct Eddge
 37 {
 38     int nex, to;
 39     Eddge(int a=-1, int b=0):nex(a), to(b) {}
 40 } edge[maxM];
 41 inline void addEddge(int u, int v)
 42 {
 43     edge[cnt] = Eddge(head[u], v);
 44     head[u] = cnt++;
 45 }
 46 inline void _add(int u, int v) { addEddge(u, v); addEddge(v, u); }
 47 int dfn[maxN], low[maxN], tot, Stap[maxN], Stop;
 48 int n;
 49 bool iscut[maxN] = {false};
 50 vector<int> V, to[maxN << 1];
 51 void Tarjan(int u, int fa)
 52 {
 53     int child = 0;
 54     V.push_back(u);
 55     dfn[u] = low[u] = ++tot;
 56     Stap[++Stop] = u;
 57     for(int i=head[u], v; ~i; i=edge[i].nex)
 58     {
 59         v = edge[i].to;
 60         if(v == fa) continue;
 61         if(!dfn[v])
 62         {
 63             child++;
 64             Tarjan(v, u);
 65             low[u] = min(low[u], low[v]);
 66             if(low[v] >= dfn[u])
 67             {
 68                 iscut[u] = true;
 69                 if(low[v] == dfn[u])
 70                 {
 71                     int p; ++n;
 72                     do
 73                     {
 74                         p = Stap[Stop--];
 75                         to[p].push_back(n);
 76                         to[n].push_back(p);
 77                     } while(p ^ v);
 78                     to[u].push_back(n);
 79                     to[n].push_back(u);
 80                 }
 81                 else
 82                 {
 83                     Stop--;
 84                     to[u].push_back(v);
 85                     to[v].push_back(u);
 86                 }
 87             }
 88         }
 89         else low[u] = min(low[u], dfn[v]);
 90     }
 91     if(!fa && child <= 1) iscut[u] = false;
 92 }
 93 ll ans[maxN] = {0}, siz[maxN << 1], all;
 94 void dfs(int u, int fa)
 95 {
 96     siz[u] = u <= N;
 97     for(int v : to[u])
 98     {
 99         if(v == fa) continue;
100         dfs(v, u);
101         siz[u] += siz[v];
102     }
103     if(u <= N)
104     {
105         ans[u] = 2LL * (all - 1);
106         if(iscut[u])
107         {
108             for(int v : to[u])
109             {
110                 if(v == fa)
111                 {
112                     ans[u] += (all - siz[u]) * (siz[u] - 1LL);
113                 }
114                 else
115                 {
116                     ans[u] += siz[v] * (all - siz[v] - 1);
117                 }
118             }
119         }
120     }
121 }
122 inline void init()
123 {
124     cnt = 0;
125     for(int i=1; i<=N; i++) head[i] = -1;
126 }
127 int main()
128 {
129     scanf("%d%d", &N, &M); n = N;
130     init();
131     for(int i=1, u, v; i<=M; i++)
132     {
133         scanf("%d%d", &u, &v);
134         _add(u, v);
135     }
136     for(int i=1; i<=N; i++)
137     {
138         if(!dfn[i])
139         {
140             V.clear();
141             Tarjan(i, 0);
142             all = V.size();
143             dfs(i, 0);
144         }
145     }
146     for(int i=1; i<=N; i++) printf("%lld
", ans[i]);
147     return 0;
148 }
原文地址:https://www.cnblogs.com/WuliWuliiii/p/13815434.html