Warm up HDU - 4612

点击打开链接

缩完点后得到一棵树 求出树的直径(最长的一条链) 然后拿割边数减去直径大小就是答案

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

struct node
{
    int v;
    int next;
    int flag;
};

node edge1[2000010],edge2[2000010];
int first1[200010],first2[200010],dfn[200010],low[200010],belong[200010];
int n,m,num,cnt,p1,p2,p,maxx;

void addedge(node* edge,int* first,int u,int v)
{
    edge[num].v=v;
    edge[num].next=first[u];
    edge[num].flag=0;
    first[u]=num++;
    return;
}

void dfsI(int cur,int fa)
{
    int tmp,i,v;
    num++,tmp=0;
    dfn[cur]=num,low[cur]=num;
    for(i=first1[cur];i!=-1;i=edge1[i].next)
    {
        v=edge1[i].v;
        if(!dfn[v])
        {
            dfsI(v,cur);
            low[cur]=min(low[cur],low[v]);
            if(low[v]>dfn[cur])
            {
                edge1[i].flag=1;
                edge1[i^1].flag=1;
            }
        }
        else if(v==fa)
        {
            if(tmp>0) low[cur]=min(low[cur],dfn[v]);
            tmp++;
        }
        else
        {
            low[cur]=min(low[cur],dfn[v]);
        }
    }
    return;
}

void dfsII(int cur)
{
    int i,v;
    for(i=first1[cur];i!=-1;i=edge1[i].next)
    {
        v=edge1[i].v;
        if(!belong[v]&&!edge1[i].flag)
        {
            belong[v]=cnt;
            dfsII(v);
        }
    }
    return;
}

void tarjan()
{
    int i,u,v;
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    num=0;
    for(u=1;u<=n;u++)
    {
        if(!dfn[u])
        {
            dfsI(u,-1);
        }
    }
    memset(belong,0,sizeof(belong));
    cnt=0;
    for(u=1;u<=n;u++)
    {
        if(!belong[u])
        {
            cnt++;
            belong[u]=cnt;
            dfsII(u);
        }
    }
    /*
    printf("***%d***\n",cnt);
    for(u=1;u<=n;u++)
    {
        printf("%d ",belong[u]);
    }
    printf("\n");
    */
    memset(first2,-1,sizeof(first2));
    num=0;
    for(u=1;u<=n;u++)
    {
        for(i=first1[u];i!=-1;i=edge1[i].next)
        {
            v=edge1[i].v;
            if(belong[u]!=belong[v])
            {
                addedge(edge2,first2,belong[u],belong[v]);
            }
        }
    }
    return;
}

void dfsIII(int cur,int fa,int dis)
{
    int i,v,res;
    if(maxx<dis)
    {
        maxx=dis;
        p=cur;
    }
    for(i=first2[cur];i!=-1;i=edge2[i].next)
    {
        v=edge2[i].v;
        if(v!=fa)
        {
            dfsIII(v,cur,dis+1);
        }
    }
    return;
}

void dfsIV(int cur,int fa,int tar,int dis)
{
    int i,v;
    if(cur==tar)
    {
        maxx=dis;
        return;
    }
    for(i=first2[cur];i!=-1;i=edge2[i].next)
    {
        v=edge2[i].v;
        if(v!=fa)
        {
            dfsIV(v,cur,tar,dis+1);
            if(maxx!=-1) return;
        }
    }
    return;
}

int main()
{
    int i,u,v;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0&&m==0) break;
        memset(first1,-1,sizeof(first1));
        num=0;
        for(i=1;i<=m;i++)
        {
            scanf("%d%d",&u,&v);
            addedge(edge1,first1,u,v);
            addedge(edge1,first1,v,u);
        }
        tarjan();
        maxx=0,p1=1;
        dfsIII(1,-1,0);
        p1=p;
        maxx=0,p2=p1;
        dfsIII(p1,-1,0);
        p2=p;
        maxx=-1;
        dfsIV(p1,-1,p2,0);
        printf("%d\n",cnt-1-maxx);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sunyutian1998/article/details/80530071