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\n", ans);
 99     for (int i = 0; i < m; i++)
100     {
101         if (ansset.find(old[i]) == ansset.end())
102             printf("%d %d\n", old[i].second, old[i].first);
103         else
104             printf("%d %d\n", old[i].first, old[i].second);
105     }
106     return 0;
107 }

 

posted @ 2016-10-18 23:10  iRedBean  阅读(435)  评论(0编辑  收藏  举报