hdu 5409 CRB and Graph(边双联通分量)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 5409 CRB and Graph(边双联通分量)相关的知识,希望对你有一定的参考价值。

题意:

给一个图一些边,保证图连通

问对于每条边,如果去除该边后使得图中一些点不连通。设这些点(u,v),要求使u尽量小,v尽量大,输出这样的(u,v)。否则输出0 0。

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const int MAXN = 1e5 + 1;
  4 typedef pair <int, int>pii;
  5 vector<pii>G[MAXN];
  6 bool isBridge[MAXN];
  7 int clk, pre[MAXN], low[MAXN];
  8 int IDX, maxv[MAXN], newIdx[MAXN], newMax[MAXN];
  9 int U[MAXN], V[MAXN];
 10 int ans[MAXN];
 11 bool vis[MAXN];
 12 int n, m;
 13 
 14 void init () {
 15     memset(isBridge, false, sizeof (isBridge)); //记录桥
 16     memset(pre, 0, sizeof (pre));   //记录的第一次访问的时间戳
 17     memset(low, 0, sizeof (low));   //本身及其子节点能回到的最早的祖先的pre值
 18     clk = 0;    //时间戳
 19     for (int i = 0; i < MAXN; i++) {
 20         G[i].clear();
 21     }
 22 }
 23 
 24 void DFS (int u, int pa) {
 25     int lowu = pre[u] = ++clk;
 26     for (int i = 0; i < G[u].size(); i++) {
 27         pii e = G[u][i];
 28         int v = e.first;
 29         int idx = e.second;
 30         if (!pre[v]) {
 31             DFS(v, u);
 32             lowu = min(lowu, low[v]);
 33             if (low[v] > pre[u]) {
 34                 isBridge[idx] = true;
 35             }
 36         } else if (pre[v] < pre[u] && v != pa) {
 37             //是反向边更新lowu
 38             lowu = min(lowu, pre[v]);
 39         }
 40     }
 41     low[u] = lowu;  //更改low[u]
 42 }
 43 
 44 void DFS2(int u, int pa) {
 45     vis[u] = true;
 46     maxv[u] = u;
 47     newIdx[u] = IDX;
 48     for (int i = 0; i < G[u].size(); i++) {
 49         pii e = G[u][i];
 50         int v = e.first;
 51         int idx = e.second;
 52         if (!isBridge[idx] && v != pa && !vis[v]) {
 53             DFS2(v, u);
 54             maxv[u] = max(maxv[u], maxv[v]);
 55         }
 56     }
 57 }
 58 
 59 void BCC_Bridge() {
 60     DFS(1, -1); //记录桥
 61     memset(vis, false, sizeof (vis));
 62     IDX = 0;
 63     for (int i = 1; i <= n; i++) {
 64         if (!vis[i]) {
 65             IDX++;
 66             DFS2(i, -1);    //缩点
 67         }
 68     }
 69     //重新记录缩后的点
 70     for (int i = 1; i <= n; i++) {
 71         G[i].clear();
 72     }
 73     for (int i = 0; i < m; i++) {
 74         if (isBridge[i]) {
 75             int u = newIdx[U[i]], v = newIdx[V[i]];
 76             G[u].push_back(make_pair(v, i));
 77             G[v].push_back(make_pair(u, i));
 78         }
 79     }
 80 }
 81 
 82 void solve (int u, int pa) {
 83     pre[u] = ++clk;
 84     ans[u] = newMax[u];
 85     for (int i = 0; i < G[u].size(); i++) {
 86         int v = G[u][i].first;
 87         if (v != pa) {
 88             solve(v, u);
 89             ans[u] = max(ans[u], ans[v]);
 90         }
 91     }
 92 }
 93 
 94 int main() {
 95     int T;
 96     scanf ("%d", &T);
 97     while (T--) {
 98         init(); //进行初始化
 99         scanf ("%d%d", &n, &m);
100         for (int i = 0; i < m; i++) {
101             int u, v;
102             scanf ("%d%d", &u, &v);
103             U[i] = u, V[i] = v;
104             G[u].push_back(make_pair(v, i));
105             G[v].push_back(make_pair(u, i));
106         }
107         BCC_Bridge();
108         for (int i = 1; i <= n; i++) {
109             newMax[newIdx[i]] = maxv[i];
110         }
111         int u;
112         for (u = 1; u <= n; u++) {
113             if (newMax[u] == n) {
114                 break;
115             }
116         }
117         memset(pre, 0, sizeof pre);
118         clk = 0;    //重新定义时间戳
119         solve (u, 0);
120         for (int i = 0; i < m; i++) {
121             int u = newIdx[U[i]],  v = newIdx[V[i]];
122             if (u == v) {
123                 printf("0 0\n");
124             } else {
125                 if (pre[u] < pre[v]) {
126                     swap(u, v);
127                 }
128                 printf("%d %d\n", ans[u], ans[u]+1);
129             }
130         }
131     }
132     return 0;
133 }

 

以上是关于hdu 5409 CRB and Graph(边双联通分量)的主要内容,如果未能解决你的问题,请参考以下文章

HDOJ 5409 CRB and Graph 无向图缩块

Graph_Master(连通分量_A)

hdu5411 CRB and Puzzle

HDU - 5411 CRB and Puzzle 矩阵快速幂

HDU 5411 CRB and puzzle (Dp + 矩阵高速幂)

[HDU - 5408] CRB and Farm