灵异事件
  • 板块灌水区
  • 楼主ChenZQ
  • 当前回复24
  • 已保存回复24
  • 发布时间2025/1/23 23:40
  • 上次更新2025/1/24 10:53:25
查看原帖
灵异事件
745358
ChenZQ楼主2025/1/23 23:40

这道题就是给一个无向图,问你加多少条边能变成一个点双连通图。

我之前不小心写成求强连通分量了所以不小心写了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;
}
2025/1/23 23:40
加载中...