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;
}