边的双连通分量问题

连通性二·边的双连通分量

题目传送:hihoCoder - 1184 - 连通性二·边的双连通分量

AC代码:

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <sstream>
#include <utility>
#include <iostream>
#include <algorithm>
#include <functional>
#define LL long long
#define INF 0x7fffffff
using namespace std;

const int maxn = 20005;
int n, m;

vector<int> G[maxn];
stack<int> s;

int vis[maxn];
int low[maxn];
int dfn[maxn];

int ans[maxn];

int cur_time, cnt;
void dfs(int u, int fa) {
    low[u] = dfn[u] = ++ cur_time;

    vis[u] = 1;
    s.push(u);
    int d = G[u].size();
    for(int i = 0; i < d; i ++) {
        int v = G[u][i];
        if(!vis[v]) {
            dfs(v, u);
            low[u] = min(low[u], low[v]);
        }
        else if(v != fa){
            low[u] = min(low[u], dfn[v]);   
        }
    }

    if(low[u] == dfn[u]) {
        cnt ++;
        stack<int> ss;
        int MIN = INF;
        while(s.top() != u) {
            MIN = min(MIN, s.top());
            ss.push(s.top());
            s.pop();
        }
        MIN = min(MIN, s.top());
        ss.push(s.top());
        s.pop();

        while(!ss.empty()) {
            ans[ss.top()] = MIN;
            ss.pop();
        }
    }
}

int main() {
    scanf("%d %d", &n, &m);
    int u, v;
    for(int i = 0; i < m; i ++) {
        scanf("%d %d", &u, &v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    while(!s.empty()) s.pop();
    cur_time = cnt = 0;
    memset(vis, 0, sizeof(vis));
    dfs(1, -1);
    printf("%d\n", cnt);
    for(int i = 1; i < n; i ++) {
        printf("%d ", ans[i]);
    }
    printf("%d\n", ans[n]);
    return 0;
}

你可能感兴趣的:(ACM,hihoCoder,双连通分量)