这道题就是给一个无向图,问你加多少条边能变成一个点双连通图。
我之前不小心写成求强连通分量了所以不小心写了vis数组上去,后来改了,但是vis数组没删,那么灵异的就来了,为什么我一注释while循环里的vis[x]=0程序就会没办法求出点双的数量???我f3都用了,没有其他地方的运算用到了vis数组啊???
#include <bits/stdc++.h>
using namespace std;
const int N = 2010;
int h[N],e[N],ne[N],idx;
void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;}
int n,m;
int dfn[N],low[N],co[N],tmm=0,cl;
int stk[N],tp,vis[N];
void dfs(int u,int f)
{
dfn[u]=low[u]=++tmm;
stk[++tp]=u,vis[u]=1;
for(int i=h[u];i!=-1;i=ne[i])
{
if(!dfn[e[i]])
{
dfs(e[i],u);
low[u]=min(low[u],low[e[i]]);
if(low[e[i]]>=dfn[u])
{
int x=-1;
cl++;
while(x!=u)
{
x=stk[tp--];
vis[x]=0;
co[x]=cl;
}
}
}
else if(e[i]!=f) low[u]=min(low[u],dfn[e[i]]);
}
}
int du[1010];
int flag[N][N];
int x[N],y[N];
int main()
{
scanf("%d%d",&n,&m);
memset(h,-1,sizeof h);
for(int i=1;i<=m;i++)
{
int a,b;scanf("%d%d",&a,&b);x[i]=a,y[i]=b;
add(a,b);add(b,a);
}
dfs(1,1);
while(tp>0)
{
int x=-1;cl++;
while(x!=1)
{
x=stk[tp--];
co[x]=cl;
}
}
cout<<cl<<endl;
for(int i=1;i<=n;i++) cout<<co[i]<<" ";cout<<endl;
for(int i=1;i<=m;i++)
{
if(!flag[co[x[i]]][co[y[i]]] && co[x[i]]!=co[y[i]])
{
flag[co[x[i]]][co[y[i]]]=flag[co[y[i]]][co[x[i]]]=1;
du[co[x[i]]]++,du[co[y[i]]]++;
}
}
int lf=0;
for(int i=1;i<=cl;i++)
{
if(du[i]==1) lf++;
}
cout<<(lf+1)/2;
}