__er @ 2023-10-02 09:07:42
样例是过不掉的
#include <bits/stdc++.h>
#include <bits/extc++.h>
std::vector<int> edge[100001], g[100001];
int n, m, mod, p, stp, tot, sum, ans, st[100001], dfn[100001], low[100001], blo[100001], size[100001], dp[100001], f[100001], tag[100001];
std::bitset<100001> vis;
void tarjan(int u) {
dfn[u] = low[u] = ++stp, vis[u] = true, st[p++] = u;
for (auto v : edge[u]) {
if (!dfn[v])tarjan(v), low[u] = std::min(low[u], low[v]);
else if (vis[v])low[u] = std::min(low[u], dfn[v]);
}
if (dfn[u] == low[u]) {
blo[u] = ++tot, vis[u] = false, p--;
while (st[p] != u)size[tot]++, blo[st[p]] = tot, vis[st[p--]] = false;
}
}
signed main() {
std::ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);
std::cin >> n >> m >> mod;
for (int i = 1, u, v; i <= m; i++)std::cin >> u >> v, edge[u].push_back(v);
for (int i = 1; i <= n; i++)if (!dfn[i])tarjan(i);
for (int i = 1; i <= n; i++) {
dp[i] = size[i], f[i] = 1;//dp[i]为大小,f[i]为种数
for (auto v : edge[i]) if (blo[i] != blo[v])g[i].push_back(v);
}
for (int u = tot; u >= 1; u--)
for (auto v : g[u]) {
if (tag[v] == u)continue;//重边不转移
tag[v] = u;
if (dp[v] < dp[u] + size[v])dp[v] = dp[u] + size[v], f[v] = f[u];
else if (dp[v] == dp[u] + size[v])f[v] = (f[v] + f[u]) % mod;
}
for (int i = 1; i <= tot; i++) {
if (dp[i] > ans)ans = dp[i], sum = f[i];
else if (dp[i] == ans)sum = (sum + f[i]) % mod;
}
return std::cout << ans << '\n' << sum, 0;
}
by zhangmingsheng3521 @ 2023-10-02 09:10:40
看不懂,但是直接dfs不好吗?(别骂我我只有橙题水平)
by __er @ 2023-10-02 09:13:15
@zhangmingsheng3521 知道可以 dfs,想知道这么写问题在哪
by __er @ 2023-10-02 09:24:23
摇一位
@cancan12345
by MinCat @ 2023-10-02 09:52:36
我来了
by MinCat @ 2023-10-02 10:00:37
@__er 你建新图的时候,下标是不是错了?
by __er @ 2023-10-02 10:03:56
@MinCat 啊?
by __er @ 2023-10-02 10:10:41
@MinCat 我拍出来是 dp 部分有问题
by __er @ 2023-10-02 10:42:29
@MinCat 好家伙调出来了就是这个的问题
这样建的答辩图和对的图调试上输出是一毛一样的我超