HDU warm up

题意

有一张联通的无向图,再加一条无向边后最少的桥的数量

  • 求桥时将边双缩点,记录桥数 ans
  • 建树,求最长路长度 bns
  • 答案为 ans-bns
  • 多组数据,注意初始化
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=2e5+10,maxm=1e6+10;
int n,m,head[maxn],num,cnt,bi,ans;
int dfn[maxn],low[maxn],input,fa[maxn],pa[maxn];
int xx[maxn],w,headd[maxn],numm,mdep,ww;
struct fy{int from,to,next,h;}q[maxm<<1];
struct ffy{int to,next;}qq[maxm<<1];
void add(int a,int b)
{
    q[++num]=(fy){a,b,head[a],++bi};head[a]=num;
    q[++num]=(fy){b,a,head[b],bi};head[b]=num;
}
void addd(int a,int b){qq[++numm]=(ffy){b,headd[a]};headd[a]=numm;}
void tar(int a)
{
    dfn[a]=low[a]=++input;xx[++w]=a;
    for(int i=head[a];i;i=q[i].next)
    {
        int b=q[i].to;if(q[i].h==pa[a])continue;
        if(!dfn[b])
        {
            pa[b]=q[i].h;tar(b);
            low[a]=min(low[a],low[b]);
            if(dfn[a]<low[b])ans++;
        }
        else low[a]=min(low[a],dfn[b]);
    }
    if(low[a]==dfn[a])
    {
        ++cnt;
        while(xx[w+1]!=a)
        {
            fa[xx[w]]=cnt;
            w--;
        }
    }
}
void dfs(int a,int fat,int dep)
{
    if(dep>mdep)
    {
        mdep=dep;
        ww=a;
    }
    for(int i=headd[a];i;i=qq[i].next)
    {
        int b=qq[i].to;if(b==fat)continue;
        dfs(b,a,dep+1);
    }
}
int main()
{
    int a,b;
    while(scanf("%d%d",&n,&m)==2)
    {
        if(n==0&&m==0)break;
        memset(head,0,sizeof head);memset(dfn,0,sizeof dfn);
        memset(low,0,sizeof low);memset(pa,0,sizeof pa);
        memset(headd,0,sizeof headd);
        num=0;cnt=0;bi=0;w=0;input=0;numm=0;ans=0;ww=0;
        for(int i=1;i<=m;i++)
        {scanf("%d%d",&a,&b);add(a,b);}
        tar(1);
        for(int i=1;i<=num;i++)
        {
            a=fa[q[i].from];b=fa[q[i].to];
            if(a!=b)addd(a,b);
        }
        mdep=0;dfs(1,0,0);
        mdep=0;dfs(ww,0,0);
        printf("%d\n",ans-mdep);
    }
    return 0;
}