[codeforces] 1000 E. We Need More Bosses

[codeforces] 1000 E. We Need More Bosses

题目链接:

E. We Need More Bosses

题目大意:

给一个 n ( 2 n 3 10 5 ) 个点, m ( n 1 m 3 10 5 ) 条边的无向图, 对于任意的两个点, 最多有多少条特殊边, 特殊边就是去掉这条边这两个点就无法互达.

可以理解为对于任意的两个点有多少条只是这两个点的割边.

思路:

首先求出割边, 然后割边的边权设为1, 其他的边权设为0, 跑一个最长链即可.

代码:

/********************************************
 *Author*        :ZZZZone
 *Created Time*  : 五  7/ 6 15:43:52 2018
 * Ended  Time*  : 五  7/ 6 23:16:45 2018
*********************************************/

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <stack>
using namespace std;
#define debug(x) std::cerr << #x << " = " << (x) << std::endl
typedef pair<int, int> PII;
typedef long long LL;
typedef unsigned long long ULL;

inline void OPEN(string s){
    freopen((s + ".in").c_str(), "r", stdin);
    freopen((s + ".out").c_str(), "w", stdout);
}

const int MAXN = 3e5;

vector<PII> edge[MAXN+5];
vector<PII> nedge[MAXN+5];
bool is_cut_p[MAXN+5], is_cut_edge[MAXN+5], vis[MAXN+5];
int pre[MAXN+5], low[MAXN+5];
int fa[MAXN+5];
int n, m, dfs_clock;
int maxlen[MAXN+5];

int find(int x){
    if(fa[x] == x) return x;
    else return fa[x] = find(fa[x]);
}

int Dfs(int u, int fa){
    int lowu = pre[u] = ++dfs_clock;
    for(int i = 0; i < edge[u].size(); i++){
        int v = edge[u][i].first;
        int id = edge[u][i].second;
        if(pre[v] == 0){
            int lowv = Dfs(v, u);
            lowu = min(lowu, lowv);
            if(lowv >= pre[u]){
                is_cut_p[u] = true;
                if(lowv > pre[u]){
                    is_cut_edge[id] = true;
                }
            }
        }
        else if(pre[v] < pre[u] && v != fa){
            lowu = min(lowu, pre[v]);
        }
    }
    low[u] = lowu;
    return lowu;
}

void Init(){
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= m; i++){
        int u, v;
        scanf("%d %d", &u, &v);
        edge[u].push_back(PII(v, i));
        edge[v].push_back(PII(u, i));
    }
    for(int i = 1; i <= n; i++){
        fa[i] = i;
    }
    Dfs(1, -1);
    for(int u = 1; u <= n; u++){
        for(int j = 0; j < edge[u].size(); j++){
            int v = edge[u][j].first;
            if(find(u) != find(v)){
                fa[find(u)] = find(v);
                nedge[u].push_back(edge[u][j]);
            }
        }
    }
}


void Solve(){
    queue<int> que;
    memset(vis, false, sizeof(vis));
    vis[1] = true;
    que.push(1);
    while(!que.empty()){
        int now = que.front(); que.pop();
        for(int i = 0; i < edge[now].size(); i++){
            int v = edge[now][i].first;
            if(vis[v]) continue;
            int id = edge[now][i].second;
            maxlen[v] = maxlen[now];
            if(is_cut_edge[id]) maxlen[v]++;
            vis[v] = true;
            que.push(v);
        }
    }
    //for(int i = 1; i <= n; i++) printf("%d ", maxlen[i]);
    int tmp = 1;
    for(int i = 1; i <= n; i++) {
        if(maxlen[i] > maxlen[tmp]) tmp = i;
    }
    memset(vis, false, sizeof(vis));
    memset(maxlen, 0, sizeof(maxlen));
    vis[tmp] = true;
    que.push(tmp);
    while(!que.empty()){
        int now = que.front(); que.pop();
        for(int i = 0; i < edge[now].size(); i++){
            int v = edge[now][i].first;
            if(vis[v]) continue;
            int id = edge[now][i].second;
            maxlen[v] = maxlen[now];
            if(is_cut_edge[id]) maxlen[v]++;
            vis[v] = true;
            que.push(v);
        }
    }
    //for(int i = 1; i <= n; i++) printf("%d ", maxlen[i]);
}

int main()
{
    Init();
    Solve();
    int ans = 0;
    for(int i = 1; i <= n; i++) ans = max(ans, maxlen[i]);
    printf("%d\n", ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ZZZZone/article/details/80982189