为什么双向边多建一次就 TLE?蒟蒻求助qwq
查看原帖
为什么双向边多建一次就 TLE?蒟蒻求助qwq
642544
makerY楼主2023/9/7 19:22

rt

在 CF 上之前一直 TLE on test #13 ,dfs 换了个写法就 TLE on test #28 (我也不知道为啥改了以后 #13 就能过了),然而还是怎么改都过不了,后面看题解发现建新图的时候可以只建一条边,因为反向的边一定会被另一个点往回建,就试了一下,发现离奇地过了,而且用时只有 233 ms,问题是就算每次多建一条边、每条边多跑一次也不可能超过 2000ms 啊,qwq。

代码如下:

#include<bits/stdc++.h>
using namespace std;
const int N=600010;
int n,m,e[N],ne[N],h[N],idx=2;
inline void add(int a,int b)
{
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int _e[N],_ne[N],_h[N],_idx=2;
inline void _add(int a,int b)
{
	_e[_idx]=b,_ne[_idx]=_h[a],_h[a]=_idx++;
}
int stk[N],top,bel[N],cntdcc,low[N],dfn[N],cnt;
inline void tarjan(int u,int lst)
{
	low[u]=dfn[u]=++cnt;
	stk[++top]=u;
	for(int i=h[u];~i;i=ne[i])
	{
		int v=e[i];
		if(i==(lst^1)) continue;
		if(!dfn[v]) tarjan(v,i),low[u]=min(low[u],low[v]);
		else low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u])
	{
		cntdcc++;
		int v=-1;
		while(v!=u)
		{
			v=stk[top--];
			bel[v]=cntdcc;
		}
	}
}

void makeG()
{
	for(int u=1;u<=n;++u)
		for(int i=h[u];~i;i=ne[i])
		{
			int v=e[i];
			if(bel[u]!=bel[v]) _add(bel[u],bel[v]);//这里再加一个_add(bel[v],bel[u])就会TLE
		}
}
int dis[N];
bool st[N];

inline void dfs(int u,int la)
{
	st[u]=1;
	for(int i=_h[u];~i;i=_ne[i])
	{
		int v=_e[i];
		if(st[v]) continue;
		st[v]=1;
		dis[v]=dis[u]+1;
		dfs(v,u);
	}
}
inline void init()
{
	memset(h,-1,sizeof h);
	memset(_h,-1,sizeof _h);
}
int main()
{
	init();
	scanf("%d%d",&n,&m);
	for(int i=1,u,v;i<=m;++i) scanf("%d%d",&u,&v),add(u,v),add(v,u);
	tarjan(1,1);
	makeG();
	dfs(1,0);
	int far=1,ans=0;
	for(int i=1;i<=n;++i) if(dis[i]>dis[far]) far=i;
	memset(st,0,sizeof st);
	memset(dis,0,sizeof dis);
	dfs(far,0);
	for(int i=1;i<=n;++i) if(dis[i]>ans) ans=dis[i];
	printf("%d",ans);
	return 0;
}
2023/9/7 19:22
加载中...