求助 tarjan缩点TLE
查看原帖
求助 tarjan缩点TLE
222578
jingkongwanglimiaoa楼主2023/8/26 09:16

rt,已验证是缩点后跑重建边dfs函数的锅

问题在于没有标记访问过的点不再访问

但这题n=5000,缩点后也已经没有环了,就算跑满也只有O(n^2),怎么会超时呢

而且才跑到三十几个点就不行了,感觉有可能是死循环了(?但是为什么会

评测记录

# include <cstdio>
# include <iostream>
# define int long long
using namespace std;
const int N = 5010;
int n,p,hp,v[N],vv[N],sta[N],ht,hk,in[N],lk[N],kk[N],tt,val[N],low[N],dfn[N],a[N],an,iz[N],qi,flk[N],fhp,az = 1,mo = 1e9+7;
struct sth{
	int ue,we;
}e[N*2],fe[N*2];
void ad(int u,int v){
	e[++hp] = {v,lk[u]};
	lk[u] = hp;
}
void fad(int u,int v){
	fe[++fhp] = {v,flk[u]};
	flk[u] = fhp;
}
void tar(int nw){
	hk++; low[nw] = dfn[nw] = hk; v[nw] = 1; 
	sta[++ht] = nw;
	for (int i = lk[nw]; i; i = e[i].we){
		if (!dfn[e[i].ue]){
			tar(e[i].ue); low[nw] = min(low[nw],low[e[i].ue]);
		}
		else if (v[e[i].ue]) low[nw] = min(low[nw],low[e[i].ue]);
	}
	if (dfn[nw]==low[nw]){
		tt++; kk[nw] = tt; val[tt] = a[nw];
		v[nw] = 0;
		while (sta[ht]!=nw){
			kk[sta[ht]]=tt;	v[sta[ht]]=0; val[tt] = min(val[tt],a[sta[ht]]); 
			ht--;
		}
		ht--;
	}
}
void dfs(int nw){
	vv[nw] = 1;
	for (int i = flk[nw]; i; i = fe[i].we){
		if (!vv[fe[i].ue]) dfs(fe[i].ue);//这里!!!不加这句判断就会寄
	}
}
signed main(){
	scanf("%lld %lld %lld",&n,&p,&qi);
	int x,y;
	for (int i = 1; i <= p; i++){
		scanf("%lld %lld",&x,&y); ad(x,y);
	}
	for (int i = 1; i <= n; i++){
		if (!dfn[i]) tar(i);
	}
	for (int u = 1; u <= n; u++){
		for (int i = lk[u]; i; i = e[i].we){
			int v = e[i].ue;
			if (kk[u]==kk[v]) continue;
			fad(kk[u],kk[v]); in[kk[v]]++;
		}
	}
	dfs(kk[qi]);
	for (int i = 1; i <= tt; i++){
		if (!vv[i] && !in[i]) an++;
	}
	printf("%lld\n",an);
	return 0;
}
2023/8/26 09:16
加载中...