[CF1000E] We Need More Bosses

Description

给定一个 (n) 个点 (m) 条边的无向图,找到两个点 (s,t),使得 (s)(t) 必须经过的边最多。

Solution

边双内的边显然都不是关键边,否则必是,于是缩点后求直径即可

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 1000005;

struct Edge
{
    int from,next,to;
} e[N];

vector <int> g[N];
int n,m,t1,t2,dfn[N],low[N],head[N],bridge[N],bel[N],tot=1,ind,cnt;

void __addedge(int u,int v)
{
    e[++tot].next=head[u];
    e[tot].to=v;
    head[u]=tot;
}

void addedge(int u,int v)
{
    __addedge(u,v);
    __addedge(v,u);
}

void tarjan(int p,int eid)
{
    dfn[p]=low[p]=++ind;
    for(int i=head[p];i!=0;i=e[i].next)
    {
        if(i!=(eid^1))
        {
            int q=e[i].to;
            if(!dfn[q])
            {
                tarjan(q,i);
                low[p]=min(low[p],low[q]);
                if(dfn[p]<low[q]) bridge[i]=bridge[i^1]=1;
            }
            else
            {
                low[p]=min(low[p],dfn[q]);
            }
        }
    }
}

void dfs(int p,int id)
{
    bel[p]=id;
    for(int i=head[p];i!=0;i=e[i].next)
    {
        int q=e[i].to;
        if(bel[q]) continue;
        if(!bridge[i]) dfs(q,id);
    }
}

void presolve()
{
    for(int i=1;i<=n;i++)
    {
        if(!dfn[i])
        {
            tarjan(i,0);
        }
    }
    for(int i=1;i<=n;i++)
    {
        if(!bel[i])
        {
            dfs(i,++cnt);
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=head[i];j!=0;j=e[j].next)
        {
            int q=e[j].to;
            if(bel[i]!=bel[q])
            {
                g[bel[i]].push_back(bel[q]);
                g[bel[q]].push_back(bel[i]);
            }
        }
    }
}

int dis[N],vis[N];

void dfs2(int p)
{
    vis[p]=1;
    for(int q:g[p])
    {
        if(!vis[q])
        {
            dis[q]=dis[p]+1;
            dfs2(q);
        }
    }
}

signed main()
{
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        cin>>t1>>t2;
        addedge(t1,t2);
    }
    presolve();
    dfs2(1);
    int p=max_element(dis+1,dis+n+1)-dis;
    memset(dis,0,sizeof dis);
    memset(vis,0,sizeof vis);
    dfs2(p);
    int q=max_element(dis+1,dis+n+1)-dis;
    cout<<dis[q]<<endl;
}

原文地址:https://www.cnblogs.com/mollnn/p/13301835.html