Luogu3119 草鉴定-Tarjan+Topsort
Solution
简单的$Tarjan$题。
有大佬现成博客 就不写了 → 传送门
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define rd read()
using namespace std; const int N = 1e5 + ;
const int inf = ~0U >> ; int n, m;
int head[N], tot, Head[N], Tot;
int low[N], dfn[N], cnt;
int st[N], tp, col, c[N], val[N], subsz[N], upsz[N], deg[N], bvis[N];
bool vis[N]; struct edge {
int nxt, fr, to;
}e[N], E[N]; queue<int> q; int read() {
int X = , p = ; char c = getchar();
for (; c > '' || c < ''; c = getchar())
if (c == '-') p = -;
for (; c >= '' && c <= ''; c = getchar())
X = X * + c - '';
return X * p;
} void add(int u, int v) {
e[++tot].to = v;
e[tot].fr = u;
e[tot].nxt = head[u];
head[u] = tot;
} void Add(int u, int v) {
E[++Tot].to = v;
E[Tot].fr = u;
E[Tot].nxt = Head[u];
Head[u] = Tot;
} void cmin(int &A, int B) {
if (A > B) A = B;
} void cmax(int &A, int B) {
if (A < B) A = B;
} void tarjan(int u) {
dfn[u] = low[u] = ++cnt;
vis[u] = ; st[++tp] = u;
for (int i = head[u]; i; i = e[i].nxt) {
int nt = e[i].to;
if (!dfn[nt]) {
tarjan(nt);
cmin(low[u], low[nt]);
}
else if (vis[nt]) cmin(low[u], dfn[nt]);
}
if (low[u] == dfn[u]) {
col++;
for (; tp;) {
int z = st[tp--];
c[z] = col;
vis[z] = ;
val[col]++;
if (z == u) break;
}
}
} void dfs(int u) {
vis[u] = ;
for (int i = Head[u]; i; i = E[i].nxt) {
int nt = E[i].to;
dfs(nt);
}
} int dfs2(int u) {
if (bvis[u] == ) return ;
if (bvis[u] == -) return ;
if (u == c[]) return ;
bool flag = false;
for (int i = Head[u]; i; i = E[i].nxt) {
int nt = E[i].to;
if (dfs2(nt)) {
flag = true;
cmax(upsz[u], upsz[nt] + val[u]);
}
}
bvis[u] = flag ? : -;
return flag;
} void Topsort() {
subsz[c[]] = val[c[]];
for (int i = ; i <= col; ++i)
if (!deg[i]) q.push(i);
for (int u; !q.empty(); ) {
u = q.front(); q.pop();
for (int i = Head[u]; i; i = E[i].nxt) {
int nt = E[i].to;
if (subsz[u] != -inf)
cmax(subsz[nt], subsz[u] + val[nt]);
deg[nt]--;
if (!deg[nt]) q.push(nt);
}
}
} int main()
{
n = rd; m = rd;
for (int i = ; i <= m; ++i) {
int u = rd, v = rd;
add(u, v);
}
for (int i = ; i <= n; ++i)
if (!dfn[i]) tarjan(i);
for (int i = ; i <= m; ++i) {
int u = e[i].fr, v = e[i].to;
u = c[u], v = c[v];
if (u == v) continue;
Add(u, v);
deg[v]++;
}
memset(vis, , sizeof(vis));
for (int i = ; i <= col; ++i) subsz[i] = -inf;
dfs(c[]);
Topsort();
bvis[c[]] = ;
upsz[c[]] = val[c[]];
for (int i = ; i <= col; ++i)
if (!vis[i]) dfs2(i);
int ans = val[c[]];
for (int i = ; i <= m; ++i) {
int u = e[i].fr, v = e[i].to;
u = c[u]; v = c[v];
if (u == v) continue;
if (!vis[v] || !(bvis[u] == )) continue;
cmax(ans, subsz[v] + upsz[u] - val[c[]]);
}
printf("%d\n", ans);
}
Luogu3119 草鉴定-Tarjan+Topsort的更多相关文章
- luogu3119/bzoj3887 草鉴定 (tarjan缩点+spfa)
首先缩一波点,就变成了一个DAG,边权是出点的大小 那我们走到某个点的时候可能会有两种状态:已经走过反边或者没走过 于是就把一个点拆成两层(x和x+N),第二层的点表示我已经走过反边了,每层中的边和原 ...
- 洛谷3119 草鉴定(tarjan)
题目大意 约翰有\(n\)块草场,编号\(1\)到\(n\),这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可能多的草场去品尝牧草. 贝西总是从\(1\)号草场出发,最后回到\(1 ...
- luogu3119 草鉴定
题目大意 给出一个有向图,问将图中的哪一个边翻转,会使节点1所在的强连通分量内的节点数最多.输出这个节点数. 题解 让我们看看暴力怎么做,即枚举每一条边,将其翻转,然后求节点1所在强连通分量节点数,然 ...
- [USACO15JAN]草鉴定Grass Cownoisseur(分层图+tarjan)
[USACO15JAN]草鉴定Grass Cownoisseur 题目描述 In an effort to better manage the grazing patterns of his cows ...
- 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur 解题报告
P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 约翰有\(n\)块草场,编号1到\(n\),这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可 ...
- 【洛谷P3119】[USACO15JAN]草鉴定Grass Cownoisseur
草鉴定Grass Cownoisseur 题目链接 约翰有n块草场,编号1到n,这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可能多的草场去品尝牧草. 贝西总是从1号草场出发,最后 ...
- 洛谷——P3119 [USACO15JAN]草鉴定Grass Cownoisseur
P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 In an effort to better manage the grazing patterns of hi ...
- 洛谷P3119草鉴定
题目 草鉴定,tarjan可以用来缩点,优化spfa的时间, 缩点之后就是一个\(DAG\)了,因此完全可以用来跑spfa上的最长路,然后枚举每条边,查看是否这条边的两个节点分别可以到达起点所在的强连 ...
- 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur (SCC缩点,SPFA最长路,枚举反边)
P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 In an effort to better manage the grazing patterns of hi ...
随机推荐
- PAT 甲级 1005 Spell It Right (20 分)
1005 Spell It Right (20 分) Given a non-negative integer N, your task is to compute the sum of all th ...
- WPF 去掉Drag a column header here to group by that column
<dxg:GridControl.View> <dxg:TableView x:Name="view" ShowGroupPanel="False&qu ...
- Spring AOP初级——入门及简单应用
在上一篇<关于日志打印的几点建议以及非最佳实践>的末尾提到了日志打印更为高级的一种方式——利用Spring AOP.在打印日志时,通常都会在业务逻辑代码中插入日志打印的语句,这实际上是 ...
- gentoo emerge L10N
gentoo 中安装软件的时候 emerge 提示 USE 中有 语言包可选安装,使用 L10N 来设置,设置方法是在USE中使用 l10n_,比如说 l10n_zh_CN 来安装中文支持包.
- 推特算法,分布式ID
package casclient_demo1.util; import java.lang.management.ManagementFactory; import java.net.InetAdd ...
- Apollo配置中心
背景: 当前我们项目,所有的配置基本都是通过本地properties 文件进行配置的,比如ip地址.端口.消息中间件和数据库连接的各种参数,当我们需要切换环境或调整参数的时候,我们必须手动的修改这些配 ...
- Android单元测试学习(一)
什么是单元测试 首先总结一下什么是单元测试,单元测试中的单元在Android或Java中可以理解为某个类中的某一个方法,因此单元测试就是针对Android或Java中某个类中的某一个方法中的逻辑代码进 ...
- 李清华201772020113《面向对象程序设计(Java)》第六周学习总结
第一部分 理论知识 1.继承 用已有类来构建新类的一种机制.新类可以继承父类的方法和域,同时可以在新类中添加新的方法和域. 已有类称为:超类.基类或父类.新类称作:子类.派生类或孩子类. 子类的构造器 ...
- HTML DOM学习
本文档参考菜鸟教程:http://www.runoob.com/htmldom/htmldom-tutorial.html 前提: DOM Document Object Model(文档对象模型) ...
- Github(远程仓库) 2
远程仓库之前就添加好了 今天弄了简单的查看远程库,提取远程库,在线修改以及本地更新修改,推送到远程仓库,删除远程仓库,参考http://www.runoob.com/git/git-remote-re ...