• Codeforces732F Tourist Reform


    求出无向图的所有边双联通分量,然后缩点就成了一颗树。

    然后我们选取最大的那个边双联通分量作为根,这样我们就可以确定所有割边的方向了。

    对于边双联通分量里面的边,我们随便dfs一下就可以把它变成强连通分量,方向也就确定了。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 vector<int> G[400010];
      5 vector<pair<int, int>> G2[400010];
      6 set<pair<int, int>> bridge;
      7 set<pair<int, int>> ansset;
      8 pair<int, int> old[400010];
      9 int vis[400010];
     10 int dfn[400010];
     11 int low[400010];
     12 int tag[400010];
     13 
     14 void get_bridge(int cur, int father, int dep)
     15 {
     16     vis[cur] = 1;
     17     dfn[cur] = low[cur] = dep;
     18     int children = 0;
     19     for (auto to : G[cur])
     20     {
     21         if (to != father && vis[to] == 1)
     22         {
     23             if (dfn[to] < low[cur])
     24                 low[cur] = dfn[to];
     25         }
     26         if (vis[to] == 0)
     27         {
     28             get_bridge(to, cur, dep + 1);
     29             children++;
     30             if (low[to] < low[cur])
     31                 low[cur] = low[to];
     32             if (low[to] > dfn[cur])
     33                 bridge.insert({cur, to}), bridge.insert({to, cur});
     34         }
     35     }
     36     vis[cur] = 2;
     37 }
     38 
     39 int dfs(int u, int tot)
     40 {
     41     int cnt = 1;
     42     vis[u] = true;
     43     tag[u] = tot;
     44     for (auto to : G[u])
     45     {
     46         if (ansset.find({u, to}) == ansset.end() && ansset.find({to, u}) == ansset.end() && bridge.find({u, to}) == bridge.end())
     47         {
     48             ansset.insert({u, to});
     49             if (!vis[to])
     50                 cnt += dfs(to, tot);
     51         }
     52     }
     53     return cnt;
     54 }
     55 
     56 void dfs2(int cur, int fa)
     57 {
     58     for (auto e : G2[cur])
     59     {
     60         int nxt = tag[e.second];
     61         if (nxt != fa)
     62         {
     63             ansset.insert({e.second, e.first});
     64             dfs2(nxt, cur);
     65         }
     66     }
     67 }
     68 
     69 int main()
     70 {
     71     int n, m;
     72     scanf("%d%d", &n, &m);
     73     int u, v;
     74     for (int i = 0; i < m; i++)
     75     {
     76         scanf("%d%d", &u, &v);
     77         G[u].push_back(v);
     78         G[v].push_back(u);
     79         old[i] = {u, v};
     80     }
     81     get_bridge(1, -1, 0);
     82     memset(vis, 0, sizeof(vis));
     83     int ans = 0;
     84     int tot = 0;
     85     int idx = 0;
     86     for (int i = 1; i <= n; i++)
     87     {
     88         if (!vis[i])
     89         {
     90             int siz = dfs(i, ++tot);
     91             if (siz > ans)
     92                 ans = siz, idx = tot;
     93         }
     94     }
     95     for (auto e : bridge)
     96         G2[tag[e.first]].push_back(e);
     97     dfs2(idx, -1);
     98     printf("%d
    ", ans);
     99     for (int i = 0; i < m; i++)
    100     {
    101         if (ansset.find(old[i]) == ansset.end())
    102             printf("%d %d
    ", old[i].second, old[i].first);
    103         else
    104             printf("%d %d
    ", old[i].first, old[i].second);
    105     }
    106     return 0;
    107 }
  • 相关阅读:
    Keep it simple & stupid
    BZOJ 2631: tree( LCT )
    BZOJ 2843: 极地旅行社( LCT )
    BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊( LCT )
    BZOJ 1742: [Usaco2005 nov]Grazing on the Run 边跑边吃草( dp )
    BZOJ 3531: [Sdoi2014]旅行( 树链剖分 )
    BZOJ 1269: [AHOI2006]文本编辑器editor( splay )
    BZOJ 2016: [Usaco2010]Chocolate Eating( 二分答案 )
    BZOJ 1734: [Usaco2005 feb]Aggressive cows 愤怒的牛( 二分答案 )
    BZOJ 2101: [Usaco2010 Dec]Treasure Chest 藏宝箱( dp )
  • 原文地址:https://www.cnblogs.com/iRedBean/p/5975503.html
Copyright © 2020-2023  润新知