zoukankan      html  css  js  c++  java
  • 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
    ");
    124             } else {
    125                 if (pre[u] < pre[v]) {
    126                     swap(u, v);
    127                 }
    128                 printf("%d %d
    ", ans[u], ans[u]+1);
    129             }
    130         }
    131     }
    132     return 0;
    133 }
  • 相关阅读:
    设置开发环境
    安装开发软件
    学习路线
    预备知识
    Spring是什么
    yum安装nginx
    .net 哈希
    Excel文件处理Demo
    汉字处理组件
    Log4Net
  • 原文地址:https://www.cnblogs.com/ouyang_wsgwz/p/7694759.html
Copyright © 2011-2022 走看看