洛谷 P3119 Grass Cownoisseur G
洛谷 P3119 Grass Cownoisseur G
题意
约翰有
贝西总是从
思路
先强连通分量缩点。
因为若一个子图内所有点都能互相到达,全部走一遍一定最优。
缩点考虑如何反转边。
如果不反转边,走出
如果反转边,必定是一个不能到达
缩点后建一张正 DAG 和一张反 DAG。
从
第一遍在反 DAG 上广搜,搜出每个点能否到达
第二遍在正 DAG 上广搜,搜出到达
第二遍广搜时搜到一个点,枚举它在反 DAG 上的边,看连接的点能否到达
若能,则更新答案,即两个点的最长路之和。
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;
int n, m, cnt, low[N], dfn[N];
bool instk[N], ok[N];
int stk[N], top, siz[N];
vector <int> E[N], Z[N], F[N];
queue <int> Q;
int dis[N], ans, sc, scc[N];
void tarjan(int x) {
low[x] = dfn[x] = ++ cnt;
stk[++ top] = x; instk[x] = 1;
for (auto y : E[x]) {
if (!dfn[y]) {
tarjan(y);
low[x] = min(low[x], low[y]);
} else if (instk[y])
low[x] = min(low[x], dfn[y]);
}
if (low[x] == dfn[x]) {
sc ++;
while (top && stk[top] != x) {
scc[stk[top]] = sc;
instk[stk[top]] = 0;
siz[sc] ++;
top --;
}
scc[stk[top]] = sc;
instk[stk[top]] = 0;
siz[sc] ++;
top --;
}
}
int main() {
cin >> n >> m;
for (int i = 1, u, v; i <= m; i ++) {
cin >> u >> v;
E[u].push_back(v);
}
for (int i = 1; i <= n; i ++) {
if (dfn[i]) continue;
tarjan(i);
}
for (int i = 1; i <= n; i ++)
for (auto v : E[i])
if (scc[i] != scc[v]) {
Z[scc[i]].push_back(scc[v]);
F[scc[v]].push_back(scc[i]);
}
Q.push(scc[1]); dis[scc[1]] = siz[scc[1]];
ans = siz[scc[1]];
while (!Q.empty()) {
int x = Q.front(); Q.pop();
ok[x] = 1;
for (auto v : F[x]) {
if (dis[v] < dis[x] + siz[v]) {
dis[v] = dis[x] + siz[v];
Q.push(v);
}
}
}
Q.push(scc[1]);
while (!Q.empty()) {
int x = Q.front(); Q.pop();
for (auto v : F[x]) {
if (!ok[v]) continue;
ans = max(ans, dis[x] + dis[v] - siz[scc[1]]);
}
for (auto v : Z[x]) {
if (dis[v] < dis[x] + siz[v]) {
dis[v] = dis[x] + siz[v];
Q.push(v);
}
}
}
cout << ans << "\n";
return 0;
}
本文来自博客园,作者:maniubi,转载请注明原文链接:https://www.cnblogs.com/maniubi/p/18397269,orz
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】