// 这回只花了45min就打完了。
// 真好。记得多手造几组。最好有暴力对拍。
#include <bits/stdc++.h>
using namespace std;
const int N = 4e5 + 10;
int dfn[N], low[N], c, dis[N], belong[N], cnt[N], tot, scc[N];
bool instk[N], inque[N];
stack <int> stk;
vector <pair <int, int> > arr;
vector <int> z[N], y[N];
void dfs(int now)
{
dfn[now] = low[now] = ++ c;
stk.push(now); instk[now] = true;
for (auto &p : z[now])
{
if (!dfn[p])
{
dfs(p);
low[now] = min(low[now], low[p]);
}
else if (instk[p])
low[now] = min(low[now], dfn[p]);
}
if (dfn[now] == low[now])
{
tot ++;
while (stk.top() != now)
{
int p = stk.top();
scc[p] = tot;
stk.pop();
instk[p] = false;
cnt[tot] ++;
}
stk.pop();
scc[now] = tot;
instk[now] = false;
cnt[tot] ++;
}
}
void spfa(int s) {
queue <int> q;
q.push(s);
inque[s] = true;
dis[s] = 0;
while (q.size()) {
int f = q.front();
q.pop();
inque[f] = false;
for (auto &u : y[f])
if (dis[u] < dis[f] + cnt[u]) {
dis[u] = dis[f] + cnt[u];
if (!inque[u]) {
inque[u] = true;
q.push(u);
}
}
}
}
int main()
{
int n, m;
cin >> n >> m;
while (m --)
{
int x, y;
cin >> x >> y;
z[x].push_back(y);
z[x + n].push_back(y + n);
z[y].push_back(x + n);
arr.push_back(make_pair(x, y));
arr.push_back(make_pair(x + n, y + n));
arr.push_back(make_pair(y, x + n));
}
for (int i = 1; i <= 2 * n; i ++)
if (!dfn[i])
dfs(i);
for (auto &u : arr)
{
int x1 = scc[u.first], y1 = scc[u.second];
if (x1 != y1)
y[x1].push_back(y1);
}
spfa(scc[1]);
cout << max(dis[scc[1]], dis[scc[n + 1]]) << '\n';
}
// 足下千里,移步换景,寰宇纷呈万花筒
洛谷 P3119【分层图】【tarjan】
最新推荐文章于 2024-07-16 10:17:07 发布