Solution - P5676 [GZOI2017] 小z玩游戏
不是???为什么栈需要清空???
思路
很简单的一个思路,把转移干成边跑 tarjan 就行了。显然 \(1\) 能到达全图。
代码
#include <bits/stdc++.h>
#define rint register int
#define rllong register long long
#define llong long long
#define N 100005
#define M 20000007
using namespace std;
int to[M], nxt[M], head[N], gsiz;
#define mkarc(u,v) (++gsiz,to[gsiz]=v,nxt[gsiz]=head[u],head[u]=gsiz)
int dfn[N], low[N], dfcnt;
int belong[N], n2, sta[N], top;
int s[N], t[N];
int n, m, ans;
inline void tarjan(rint u){
dfn[u] = low[u] = ++dfcnt;
sta[++top] = u;
for(rint i = head[u]; i; i = nxt[i]){
rint v = to[i];
if(!dfn[v]){
tarjan(v);
low[u] = min(low[u], low[v]);
}
else if(!belong[v]) low[u] = min(low[u], dfn[v]);
}
if(dfn[u] == low[u]){
++n2;
while(sta[top+1] != u)
belong[sta[top--]] = n2;
}
return;
}
int _main(){
for(rint i = 1; i <= n; ++i)
dfn[i] = low[i] = head[i] = belong[i] = sta[i] = 0;
scanf("%d", &m), n = n2 = ans = gsiz = dfcnt = 0;
for(rint i = 1; i <= m; ++i)
scanf("%d", &s[i]), n = max(n, s[i]);
for(rint i = 1; i <= m; ++i)
scanf("%d", &t[i]), n = max(n, t[i]);
for(rint i = 1; i <= m; ++i)
mkarc(s[i], t[i]);
for(rint i = 1; i <= n; ++i)
for(rint j = 2; i*j <= n; ++j)
mkarc(i, i*j);
tarjan(1);
for(rint i = 1; i <= m; ++i)
if(belong[s[i]] == belong[t[i]] && belong[s[i]] != 0) ++ans;
printf("%d\n", ans);
return 0;
}
int ccf;
int main(){
scanf("%d", &ccf);
while(ccf--) _main();
return 0;
}