zoukankan      html  css  js  c++  java
  • UVALive 5135 Mining Your Own Bussiness【tarjan点双】

    LINK1

    LINK2


    题目大意

    给你一个无向连通图,让你给一些点染上黑色,需要满足染色之后,断开任意一个节点,要满足任意一个联通块中剩下的节点中至少有一个黑点

    思路

    一开始想的是把每一个点双联通分量都把除了割点的size乘上

    然后发现随手卡掉

    然后发现一下性质

    首先所有相邻点双联通分量一定有公共的割点

    如果一个双联通分量里面只包含了一个割点,那么如果断掉这个割点那么这个双联通分量就被孤立了

    所以这样的双联通分量至少选择一个点

    然后如果一个双联通分量有大于等于两个割点,就算一个被割掉了另外一边至少连接着1个只有一个割点的点双联通分量

    那么就很容易做了

    特判一下如果整张图都是一个双联通分量那么就是任意选两个点就可以了


    //Author: dream_maker
    #include<bits/stdc++.h>
    using namespace std;
    //----------------------------------------------
    //typename
    typedef long long ll;
    //convenient for
    #define fu(a, b, c) for (int a = b; a <= c; ++a)
    #define fd(a, b, c) for (int a = b; a >= c; --a)
    #define fv(a, b) for (int a = 0; a < (signed)b.size(); ++a)
    //inf of different typename
    const int INF_of_int = 1e9;
    const ll INF_of_ll = 1e18;
    //fast read and write
    template <typename T>
    void Read(T &x) {
      bool w = 1;x = 0;
      char c = getchar();
      while (!isdigit(c) && c != '-') c = getchar();
      if (c == '-') w = 0, c = getchar();
      while (isdigit(c)) {
        x = (x<<1) + (x<<3) + c -'0';
        c = getchar();
      }
      if (!w) x = -x;
    }
    template <typename T>
    void Write(T x) {
      if (x < 0) {
        putchar('-');
        x = -x;
      }
      if (x > 9) Write(x / 10);
      putchar(x % 10 + '0');
    }
    //----------------------------------------------
    typedef pair<int, int> pi;
    #define fi first
    #define se second
    const int N = 5e4 + 10;
    struct Edge {
      int v, nxt;
    } E[N << 1];
    stack<pi > st;
    int head[N], tot = 0, ind = 0, cnt_bcc = 0;
    int n, m, dfn[N], low[N], siz[N], bel[N];
    bool iscut[N];
    vector<int> g[N];
    void init() {
      fu(i, 1, N - 1) dfn[i] = low[i] = bel[i] = head[i] = siz[i] = 0, iscut[i] = 0;
      tot = ind = cnt_bcc = 0;
    }
    void add(int u, int v) {
      E[++tot] = (Edge) {v, head[u]};
      head[u] = tot;
    }
    void tarjan(int u, int fa) {
      dfn[u] = low[u] = ++ind;
      int num = 0;
      for (int i = head[u]; i; i = E[i].nxt) {
        int v = E[i].v;
        if (v == fa) continue;
        if (!dfn[v]) {
          st.push(pi(u, v));
          ++num;
          tarjan(v, u);
          low[u] = min(low[u], low[v]);
          if (low[v] >= dfn[u]) {
            iscut[u] = 1;
            g[++cnt_bcc].clear();
            pi now;
            do {
              now = st.top(); st.pop();
              if (bel[now.fi] != cnt_bcc) {
                g[cnt_bcc].push_back(now.fi);
                bel[now.fi] = cnt_bcc;
              } 
              if (bel[now.se] != cnt_bcc) {
                g[cnt_bcc].push_back(now.se);
                bel[now.se] = cnt_bcc;
              }
            } while (now.fi != u || now.se != v);
          }
        } else low[u] = min(low[u], dfn[v]);
      }
      if (num < 2 && !fa) iscut[u] = 0;
    }
    void solve() {
      n = 0;
      init();
      fu(i, 1, m) {
        int u, v;
        Read(u), Read(v);
        add(u, v);
        add(v, u);
        n = max(n, max(u, v));
      }
      tarjan(1, 0);
      if (cnt_bcc == 1) {
        Write(2), putchar(' ');
        Write(ll(n) * ll(n - 1) / 2), putchar('
    ');
      } else {
        ll ans1 = 0, ans2 = 1;
        fu(i, 1, cnt_bcc) {
          int cntnow = 0;
          fv(j, g[i])
            if (iscut[g[i][j]]) ++cntnow;
          if (cntnow == 1) 
            ++ans1, ans2 *= (ll) g[i].size() - 1;
        }
        Write(ans1), putchar(' ');
        Write(ans2), putchar('
    ');
      }
    }
    int main() {
    #ifdef dream_maker
      freopen("input.txt", "r", stdin);
    #endif
      int id = 0;
      while (1) {
        Read(m);
        if (!m) return 0;
        printf("Case %d: ", ++id);
        solve();
      }
      return 0;
    }
    
  • 相关阅读:
    redis 五种数据结构详解(string,list,set,zset,hash)
    推荐一个同步Mysql数据到Elasticsearch的工具
    一些经验,用来鉴别不太靠谱的公司或工作(面试是双向的,是你最好的了解这个公司的机会)
    OpenSSL 使用 base64 编码/解码(liang19890820)
    Qt之QEvent(所有事件的翻译)
    Go 在 Windows 上用户图形界面 GUI 解决方案 Go-WinGUI 国产(使用cef 内核)
    卷积神经网络CNN
    Event Driven Architecture
    wineshark分析抓取本地回环包
    僵尸进程与孤儿进程
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9899025.html
Copyright © 2011-2022 走看看