再来点boss题解

再来点boss

给定一个 n 个点 m 条边的无向图,保证图连通。找到两个点 s,t ,使得 s 到 t 必须经过的边最多(一条边无论走哪条路线这一条边都经过,这条边就是必须经过的边)。

首先我们要知道知道同一个边双连通分量中,任意两点之间存在至少两条无重边的简单路径。

我们可以发现同一个边双内的点之间没有必须经过的边。所以在这一道题目中,我们只需要把给我们的图给缩点缩成一棵树,然后跑两边 dfs 求树的直径即可,也就是 2 个板子套一下就可以了。

复制代码
#include<bits/stdc++.h>
using namespace std;
const int N=1200100;
int n,m,idx=1,cnt,in1,in2,num,p,q;
int to[N],nxt[N],head[N],rhead[N];
int dfn[N],low[N],bridge[N],rid[N];
int dis[N];
void add(int h[],int u,int v)
{
    idx++;
    to[idx]=v;
    nxt[idx]=h[u];
    h[u]=idx;
}
void tarjan(int s,int last)//缩点板子,不必多说
{
    dfn[s]=low[s]=++cnt;
    for(int i=head[s];i;i=nxt[i])
    {
        int v=to[i];
        if(i==(last^1)) 
            continue;
        if(!dfn[v])
        {
            tarjan(v,i);
            low[s]=min(low[s],low[v]);
            if(dfn[s]<=low[v])//直接就是一座桥
            {
                bridge[i]=bridge[i^1]=1;
            }
        }
        else 
            low[s]=min(low[s],dfn[v]);
    }
}
void dfs_0(int s)//跑2遍dfs,求树的直径
{
    rid[s]=num;
    for(int i=head[s];i;i=nxt[i])
    {
        int v=to[i];
        if(bridge[i]||rid[v]) 
            continue;
        dfs_0(v);
    }
}
void dfs_1(int s,int fa,int &u)
{
    for(int i=rhead[s];i;i=nxt[i])
    {
        int v=to[i];
        if(v==fa) 
            continue;
        dis[v]=dis[s]+1;
        if(dis[0]<dis[v])
        {
            dis[0]=dis[v];
            u=v;
        }
        dfs_1(v,s,u);
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&in1,&in2);
        add(head,in1,in2);
        add(head,in2,in1);
    }
    tarjan(1,-1);
    for(int i=1;i<=n;i++)
    {
        if(!rid[i])
        {
            num++;
            dfs_0(i);
        }
    }
    for(int s=1;s<=n;s++)
    {
        for(int i=head[s];i;i=nxt[i])
        {
            if(rid[s]!=rid[to[i]])
            {
                add(rhead,rid[s],rid[to[i]]);
            }
        }
    }
    dis[1]=0;
    dfs_1(1,0,p);
    dis[0]=dis[p]=0;
    dfs_1(p,0,q);
    cout<<dis[0]<<endl;
    return 0;
}
相关推荐
汉克老师4 小时前
第十四届蓝桥杯青少组C++选拔赛[2023.2.12]第二部分编程题(5、机甲战士)
c++·算法·蓝桥杯·01背包·蓝桥杯c++·c++蓝桥杯
Mr_Xuhhh5 小时前
项目需求分析(2)
c++·算法·leetcode·log4j
c++bug6 小时前
六级第一关——下楼梯
算法
Morri36 小时前
[Java恶补day53] 45. 跳跃游戏Ⅱ
java·算法·leetcode
林木辛6 小时前
LeetCode热题 15.三数之和(双指针)
算法·leetcode·双指针
AndrewHZ6 小时前
【3D算法技术】blender中,在曲面上如何进行贴图?
算法·3d·blender·贴图·三维建模·三维重建·pcg
Jared_devin7 小时前
二叉树算法题—— [蓝桥杯 2019 省 AB] 完全二叉树的权值
数据结构·c++·算法·职场和发展·蓝桥杯
AI 嗯啦8 小时前
数据结构深度解析:二叉树的基本原理
数据结构·算法
和光同尘@9 小时前
66. 加一 (编程基础0到1)(Leetcode)
数据结构·人工智能·算法·leetcode·职场和发展
CHEN5_029 小时前
leetcode-hot100 11.盛水最多容器
java·算法·leetcode