题目大意:给定一个无向连通图,问天几条边可以使它变成一个双连通图。
算法思路:tarjan算法模板。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define MAXN 10005
int n,m;
typedef struct Edge
{
int u;
int v;
int c;
};
Edge edges[MAXN*20];
int head[MAXN],next[MAXN],a,b,e,times,cnt;
int dfn[MAXN],low[MAXN],group[MAXN],degree[MAXN];
bool visited[MAXN];
stack<int>stk;
void addNode(int u,int v)
{
edges[e].u=u;
edges[e].v=v;
next[e]=head[u];
head[u]=e++;
}
void tarjan(int u,int fa)
{
dfn[u]=low[u]=times++;
stk.push(u);
bool flag=true;
for(int i=head[u];i+1;i=next[i])
{
if(flag&&edges[i].v==fa)
{
flag=false;
continue;
}
if(!dfn[edges[i].v])
{
tarjan(edges[i].v,u);
low[u]=min(low[u],low[edges[i].v]);
}
else
{
low[u]=min(low[u],dfn[edges[i].v]);
}
}
if(low[u]==dfn[u])
{
int v;
do
{
v=stk.top();
stk.pop();
group[v]=cnt;
}while(v!=u);
cnt++;
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
e=0;
cnt=1;
times=0;
memset(head,-1,sizeof(head));
memset(next,-1,sizeof(next));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(visited,false,sizeof(visited));
memset(degree,0,sizeof(degree));
memset(group,0,sizeof(group));
for(int i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
addNode(a,b);
addNode(b,a);
}
bool isem=true;
tarjan(1,-1);
for(int i=1;i<=n;i++)
{
for(int j=head[i];j+1;j=next[j])
{
if(group[i]!=group[edges[j].v])
{
degree[group[i]]++;
degree[group[edges[j].v]]++;
}
}
}
int ans=0;
for(int i=1;i<cnt;i++)
{
if(degree[i]==2)
{
ans++;
}
}
printf("%d\n",(ans+1)/2);
}
return 0;
}