hdu 4612 (双联通+树形DP)

加一条边后最少还有多少个桥,先Tarjan双联通缩点,

然后建树,求出树的直径,在直径起点终点加一条边去的桥最多,





 

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stack>
#define N 200001
using namespace std;
int belong[N],head[N],num,ins[N],n,dfs[N],low[N],idx,ans,num1;
struct edge
{
    int st,ed,next;
}E[N*10],e[N*10];
void addedge(int x,int y)
{
    E[num].st=x;
    E[num].ed=y;
    E[num].next=head[x];
    head[x]=num++;
}
void Addedge(int x,int y)
{
    e[num1].st=x;
    e[num1].ed=y;
    e[num1].next=head[x];
    head[x]=num1++;
}
stack<int>Q;
void Tarjan(int u,int father)
{
   int i,j,v,flag=0;
    low[u]=dfs[u]=idx++;
    Q.push(u);
    for(i=head[u];i!=-1;i=E[i].next)
    {
        j=E[i].ed;
        if(dfs[j]==-1)
        {
            Tarjan(j,u);
            low[u]=low[u]>low[j]?low[j]:low[u];
        }
        else if(j==father)
        {
            if(flag)
                low[u]=low[u]>dfs[j]?dfs[j]:low[u];
            flag++;
            
        }
        else low[u]=low[u]>dfs[j]?dfs[j]:low[u];
        
    }
    if(dfs[u]==low[u])
    {
        do
        {
            v=Q.top();
            Q.pop();
            belong[v]=ans;
        }while(v!=u);
        ans++;
    }
}
void read()
{
    memset(head,-1,sizeof(head));
    num1=0;
    for(int i=0;i<num;i+=2)
    {
        int x=belong[E[i].st];
        int y=belong[E[i].ed];
        if(x==y)continue;
        Addedge(x,y);
        Addedge(y,x);
    }
}
int dis;
int dist(int u)
{
    ins[u]=1;
    int max=0,mmax=0;
    for(int i=head[u];i!=-1;i=e[i].next)
    {
        int v=e[i].ed;
        if(ins[v]==1)continue;
        int temp=dist(v);
        if(temp>mmax)
        {
            max=mmax;
            mmax=temp;            
        }
        else if(temp>max)
        {
            max=temp;
        }
    }
    if(dis<(mmax+max+1))
        dis=mmax+max+1;
    return mmax+1;
}
int main()
{
    int i,m,x,y;
    while(scanf("%d%d",&n,&m),n||m)
    {
        memset(head,-1,sizeof(head));
        num=0;
        for(i=0;i<m;i++)
        {
            scanf("%d%d",&x,&y);
            addedge(x,y);
            addedge(y,x);
        }
        memset(dfs,-1,sizeof(dfs));
        memset(low,-1,sizeof(low));
        memset(ins,0,sizeof(ins));
        idx=ans=0;
        Tarjan(1,-1);
        read();
        memset(ins,0,sizeof(ins));
        dis=0;
        dist(1);
        printf("%d\n",ans-dis);
    }
    return 0;
}


 

 

posted on 2013-07-31 19:58  you Richer  阅读(203)  评论(0编辑  收藏  举报