zoukankan      html  css  js  c++  java
  • [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 }
  • 相关阅读:
    java 配置Apache,Tomcat的gzip压缩功能
    java并发编程中CountDownLatch和CyclicBarrier的使用
    Java常用工具包 Jodd
    Servlet 3特性:异步Servlet
    tomcat7安装
    2013-Hessian
    使用commons configuration管理配置文件
    2013-JVisualVM远程监听服务器内存进程
    Jquery复选框
    Jquery选择器总结
  • 原文地址:https://www.cnblogs.com/WuliWuliiii/p/13815434.html
Copyright © 2011-2022 走看看