codeforces 732F (桥)

来源:互联网 发布:linux 目录覆盖 编辑:程序博客网 时间:2024/06/05 01:17

题目链接:点击这里

题意:给出一个无向图,定义有向图的瓶颈点是能到达的点数最少的点,瓶颈值就是瓶颈点最少的点数。现在要给每个边定一个方向最大化瓶颈值。

显然如果是一个环,那么能够构造出一种最优情况:每个边按照环的顺序定义方向,这样每一个点都能到达其他的点。所以按照环缩点,容易发现最大值就是最大的联通分量(其他的联通分量都连向他)。所以就是找出所有的桥,每次dfs一个联通分量设置方向,最后联通分量直接bfs设置桥的方向。

#include <cstdio>#include <cmath>#include <algorithm>#include <iostream>#include <vector>#include <cstring>#include <queue>using namespace std;#define maxn 400005#define maxm maxn<<1struct node {    int u, v, next;    bool is;}edge[maxm];int head[maxn], cnt;int n, m;int dfs_clock, low[maxn], pre[maxn];int ans[maxn][2];void add_edge (int u, int v) {    edge[cnt].is = 0;    edge[cnt].u = u, edge[cnt].v = v, edge[cnt].next = head[u], head[u] = cnt++;}void find_cut (int u, int father) {     pre[u] = low[u] = ++dfs_clock;    for (int i = head[u]; i+1; i = edge[i].next) {        int v = edge[i].v;        if (v == father) continue;        if (!pre[v]) {            find_cut (v, u);            if (low[v] <= pre[u]) {}            else {                edge[i].is = edge[i^1].is = 1;            }            low[u] = min (low[u], low[v]);        }        else {            low[u] = min (low[u], pre[v]);        }    }}int cc;void dfs (int u, int father) {    cc++;    pre[u] = 1;    for (int i = head[u]; i+1; i = edge[i].next) {        int v = edge[i].v;        if (edge[i].is) continue;        ans[i>>1][0] = u, ans[i>>1][1] = v;        if (!pre[v]) dfs (v, u);    }}void bfs (int s) {    queue <int> gg;    while (!gg.empty ()) gg.pop ();    memset (pre, 0, sizeof pre);    gg.push (s);    pre[s] = 1;    while (!gg.empty ()) {        int u = gg.front (); gg.pop ();        for (int i = head[u]; i+1; i = edge[i].next) {            int v = edge[i].v;            if (pre[v]) continue;            if (edge[i].is) {                ans[i>>1][0] = v, ans[i>>1][1] = u;            }            gg.push (v);            pre[v] = 1;        }    }}void solve () {    memset (pre, 0, sizeof pre);    int Max = 0, from;    for (int i = 1; i <= n; i++) if (!pre[i]) {        cc = 0;        dfs (i, 0);        if (cc > Max) {            Max = cc, from = i;        }    }    bfs (from);    cout << Max << endl;    for (int i = 0; i < m; i++) {        cout << ans[i][0] << " " << ans[i][1] << endl;    }}int main () {    ios::sync_with_stdio (0);    cin >> n >> m;    memset (head, -1, sizeof head);    cnt = 0;    for (int i = 0; i < m; i++) {        int u, v;        cin >> u >> v;        add_edge (u, v);        add_edge (v, u);    }    dfs_clock = 0;    find_cut (1, 0);    solve ();    return 0;}
0 0
原创粉丝点击