RT,不知道哪里的问题,思路就是缩点拓扑然后DAG正反dp,但是样例都过不了
#include <bits/stdc++.h>
#define rint register int
#define int long long
#define endl '\n'
using namespace std;
const int N = 1e5 + 5;
const int M = N << 1;
int n, m;
int x[N], y[N];
int h[N], e[M], ne[M], idx;
int hc[N], vc[M], nc[M], tc;
int stk[N], ins[N], c[N], dfn[N], low[N];
int f[N][2], in[N];
bool v[N][2];
vector<int> scc[N];
int top, num, cnt;
void add(int a, int b)
{
e[++idx] = b, ne[idx] = h[a], h[a] = idx;
}
void add_c(int a, int b)
{
vc[++tc] = b, nc[tc] = hc[a], hc[a] = tc, in[b]++;
}
void tarjan(int x)
{
dfn[x] = low[x] = ++num;
stk[++top] = x, ins[x] = 1;
for (rint i = h[x]; i; i = ne[i])
{
int y = e[i];
if (!dfn[y])
{
tarjan(y);
low[x] = min(low[x], low[y]);
}
else if (ins[y]) low[x] = min(low[x], dfn[y]);
}
if (dfn[x] == low[x])
{
cnt++; int y;
do
{
y = stk[top--], ins[y] = 0;
c[y] = cnt, scc[cnt].push_back(y);
} while (x != y);
}
}
void toposort(int k)
{
queue<int> q;
for (rint i = 1; i <= cnt; i++)
if (!in[i])
q.push(i);
while (!q.empty())
{
int x = q.front();
q.pop();
f[x][k] += scc[x].size();
for (rint i = hc[i]; i; i = nc[i])
{
int y = vc[i];
in[y]--;
if (v[x][k])
{
v[y][k] = 1;
f[y][k] = max(f[x][k], f[y][k]);
}
if (!in[y]) q.push(y);
}
}
}
signed main()
{
cin >> n >> m;
for (rint i = 1; i <= m; i++)
{
cin >> x[i] >> y[i];
add(x[i], y[i]);
}
for (rint i = 1; i <= n; i++)
if (!dfn[i])
tarjan(i);
int s = c[1];
v[s][0] = v[s][1] = 1;
for (rint x = 1; x <= idx; x++)
{
for (rint i = h[x]; i; i = ne[i])
{
int y = e[i];
if (c[x] == c[y]) continue;
add_c(c[x], c[y]);
}
}
toposort(0);
memset(hc, 0, sizeof hc);
memset(vc, 0, sizeof vc);
memset(nc, 0, sizeof nc);
memset(in, 0, sizeof in);
tc = 0;
for (rint x = 1; x <= idx; x++)
{
for (rint i = h[x]; i; i = ne[i])
{
int y = e[i];
if (c[x] == c[y]) continue;
add_c(c[y], c[x]);
}
}
toposort(1);
int ans = scc[s].size();
for (rint i = 1; i <= cnt; i++)
{
int a = c[x[i]], b = c[y[i]];
if (v[a][1] && v[b][0])
{
ans = max(ans, f[a][1] + f[b][0] - (int)scc[s].size());
}
}
cout << ans << endl;
return 0;
}