hdu-4612(无向图缩点+树的直径)

题意:给你n个点和m条边的无向图,问你如果多加一条边的话,那么这个图最少的桥是什么

解题思路:无向图缩点和树的直径,用并查集缩点;

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxm=2005000;
const int maxn=200500;
struct Edge
{
    int next;int id;int to;
}edge[maxm];
int head[maxn],dist[maxn],f[maxn],low[maxn],dfn[maxn],visit[maxn];
int n,m,cnt,ans,step;
void init()
{
    memset(dist,0,sizeof(dist));
    memset(visit,0,sizeof(visit));
    memset(head,-1,sizeof(head));
    memset(low,0,sizeof(low));
    memset(dfn,0,sizeof(dfn));
    for(int i=1;i<=n;i++)
        f[i]=i;
    step=ans=cnt=0;
}
int findf(int u)
{
    if(u==f[u])
        return u;
    else
    {
        f[u]=findf(f[u]);
        return f[u];
    }
}
void join(int u,int v)
{
    int t1=findf(u);int t2=findf(v);
    if(t1!=t2)
        f[t2]=t1;
}
void add(int u,int v,int id)
{
    edge[cnt].next=head[u];edge[cnt].to=v;edge[cnt].id=id;head[u]=cnt++;
    edge[cnt].next=head[v];edge[cnt].to=u;edge[cnt].id=id;head[v]=cnt++;
}
void tarjan(int u,int fa)
{
    low[u]=dfn[u]=++step;
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].to;int id=edge[i].id;
        if(fa==id)
            continue;
        if(!dfn[v])
        {
            tarjan(v,id);
            low[u]=min(low[u],low[v]);
            if(dfn[u]<low[v])
            {
                ans++;
            }
            else
            {
                join(u,v);
            }
        }
        else
        {
            low[u]=min(low[u],dfn[v]);
        }
    }
}
void bfs(int u)
{
    visit[u]=1;dist[u]=0;
    queue<int>q;
    q.push(u);
    while(!q.empty())
    {
        int x=q.front();q.pop();
        for(int i=head[x];i!=-1;i=edge[i].next)
        {
            int v=edge[i].to;
            if(visit[v])
                continue;
            if(findf(x)==findf(v))
            {
                q.push(v);dist[v]=dist[x];visit[v]=1;
            }
            else
            {
                q.push(v);dist[v]=dist[x]+1;visit[v]=1;
            }
        }
    }
}
int main()
{
    int x,y;
    while(scanf("%d%d",&n,&m)&&n&&m)
    {
        init();
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            add(x,y,i);
        }
        tarjan(1,0);
        bfs(1);
        int maxx=0;int pos=1;
        for(int i=1;i<=n;i++)
        {
            if(maxx<dist[i])
            {
                maxx=dist[i];pos=i;
            }
        }
        memset(visit,0,sizeof(visit));memset(dist,0,sizeof(dist));
        bfs(pos);
        maxx=0;
        for(int i=1;i<=n;i++)
        {
            if(maxx<dist[i])
                maxx=dist[i];
        }
        printf("%d\n",ans-maxx);
    }
}

 

posted @ 2019-03-31 17:17  荒岛的龟  阅读(364)  评论(0编辑  收藏  举报