2013 Multi-University Training Contest 1 Warm up HDU 4612

来源:互联网 发布:网络枪战手游排行榜 编辑:程序博客网 时间:2024/06/06 16:30

思路:用tarjan算出无向连通图的连通分量的个数,那么桥的个数也就是连通分量个数减一,将在同个连通分量内的点进行缩点,最后将不同连通分量之间连边,求一遍新图(是一棵树)的最长路径(树的直径),显然,最长的直径加上头尾一条边形成一个环,可以减少相同长度的桥,也就是加上一条边后,原图能达到最少的桥数。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#pragma comment(linker,"/STACK:102400000,102400000")#define maxn 200005#define maxm 2000005struct Enode{    int to,next;} edge[maxm];int head[maxn],esum;int x[maxm],y[maxm];int dfn[maxn],low[maxn],stack[maxn],belong[maxn],index,top,bcnt;int dis[maxn],que[maxn];bool vis[maxn],instack[maxn];int n,m;void init(){    memset(head,-1,sizeof(head));    esum=0;}inline void add(int u,int v){    edge[esum].to=v,edge[esum].next=head[u],head[u]=esum++;}void bfs(int s){    memset(vis,0,sizeof(vis));    memset(dis,0,sizeof(dis));    int l,r,v,u;    l=r=0;    vis[s]=1;    dis[s]=0;    que[r++]=s;    while(r>l)    {        u=que[l++];        for(int i=head[u]; ~i; i=edge[i].next)            if(!vis[v=edge[i].to])            {                vis[v]=1;                dis[v]=dis[u]+1;                que[r++]=v;            }    }}int treediameter(int s){    int u,maxl;    bfs(s);    maxl=0,u=s;    for(int i=1; i<=n; i++)        if(dis[i]>maxl)            u=i,maxl=dis[i];    bfs(u);    maxl=0;    for(int i=1; i<=n; i++)        if(dis[i]>maxl)            maxl=dis[i];    return maxl;}void tarjan(int now,int pre){    int v;    dfn[now]=low[now]=++index;    instack[now]=true;    stack[++top]=now;    for (int i=head[now]; ~i; i=edge[i].next)    {        v=edge[i].to;        if(i==pre) continue;        if (!dfn[v])        {            tarjan(v,i^1);            if (low[v]<low[now])                low[now]=low[v];        }        else if (instack[v] && dfn[v]<low[now])            low[now]=dfn[v];    }    if (dfn[now]==low[now])    {        bcnt++;        do        {            v=stack[top--];            instack[v]=false;            belong[v]=bcnt;        }        while (v!=now);    }}void solve(){    int i;    top=bcnt=index=0;    memset(dfn,0,sizeof(dfn));    for (i=1; i<=n; i++)        if (!dfn[i])            tarjan(i,-1);}int main(){    while(~scanf("%d%d",&n,&m))    {        if(!n&&!m) break;        init();        for(int i=0; i<m; i++)        {            scanf("%d%d",&x[i],&y[i]);            add(x[i],y[i]);            add(y[i],x[i]);        }        solve();        init();        for(int i=0; i<m; i++)            if(belong[x[i]]!=belong[y[i]])                {                    add(belong[x[i]],belong[y[i]]);                    add(belong[y[i]],belong[x[i]]);                }        int maxlen=treediameter(1);        printf("%d\n",bcnt-1-maxlen);    }    return 0;}


原创粉丝点击