#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
struct Edge
{
int from,to,tag;
};
int n,m,dfn[200000+5],low[200000+5],vis[200000+5],dep,num,p[200000+5];
vector<Edge>edges;
vector<int>G[200000+5];
vector<int>g[200000+5];
void AddEdge(int from,int to)
{
int i,flag=0;
for(i=0; i<G[from].size(); i++)
if(edges[G[from][i]].to==to)
{
edges[G[from][i]].tag++;
flag=1;
break;
}
if(!flag)
{
Edge tp;
tp.from=from;
tp.to=to;
tp.tag=0;
edges.push_back(tp);
G[from].push_back(edges.size()-1);
}
}
void dfs(int u,int fa)
{
dfn[u]=low[u]=++dep;
for(int i=0; i<G[u].size(); i++)
{
Edge t=edges[G[u][i]];
if(!vis[t.to])
{
vis[t.to]=1;
dfs(t.to,u);
low[u]=min(low[u],low[t.to]);
if(low[t.to]>dfn[u]&&!t.tag)
{
g[u].push_back(t.to);
g[t.to].push_back(u);
num++;
}
}
else if(t.to!=fa||t.tag)
low[u]=min(low[u],dfn[t.to]);
}
}
void dfs2(int u,int bcc)
{
p[u]=bcc;
for(int i=0; i<G[u].size(); i++)
{
int to=edges[G[u][i]].to;
bool f=true;
for(int j=0;j<g[u].size();j++)
{
int v=g[u][j];
if(v==to)
{
f=false;
break;
}
}
if(!f||vis[to]) continue;
vis[to]=1;
dfs2(to,bcc);
}
}
void dfs3(int u,int dep)
{
vis[u]=dep;
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(vis[v]==-1)
dfs3(v,dep+1);
}
}
void find_bcc()
{
int i,j,bcc,u,v;
memset(vis,0,sizeof(vis));
num=dep=0;
for(i=1; i<=n; i++)
{
if(!vis[i])
{
vis[i]=1;
dfs(i,-1);
}
}
memset(vis,0,sizeof(vis));
memset(p,0xff,sizeof(p));
bcc=0;
for(i=1; i<=n; i++)
{
if(!vis[i])
{
bcc++;
vis[i]=1;
dfs2(i,bcc);
}
}
for(i=0;i<=n;i++)
G[i].clear();
for(i=1;i<=n;i++)
for(j=0;j<g[i].size();j++)
{
int v=g[i][j];
if(p[v]!=p[i])
{
G[p[i]].push_back(p[v]);
}
}
memset(vis,0xff,sizeof(vis));
dfs3(1,1);
int flag,maxn=0;
for(i=1;i<=bcc;i++)
{
if(vis[i]>=maxn)
{
flag=i;
maxn=vis[i];
}
}
memset(vis,0xff,sizeof(vis));
dfs3(flag,0);
maxn=0;
for(i=1;i<=bcc;i++)
{
if(vis[i]>maxn)
maxn=vis[i];
}
printf("%d\n",num-maxn);
}
int main()
{
int _,i,u,v;
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0) break;
edges.clear();
for(i=0; i<=n; i++)
{
G[i].clear();
g[i].clear();
}
for(i=1; i<=m; i++)
{
scanf("%d%d",&u,&v);
AddEdge(u,v);
AddEdge(v,u);
}
find_bcc();
}
return 0;
}
hdu 4612 Warm up 边双连通分量+树的直径
最新推荐文章于 2018-07-05 15:48:50 发布