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 ...
随机推荐
- Spring Cloud(Dalston.SR5)--Zuul 网关-过滤器
Spring Cloud 为 HTTP 请求的各个阶段提供了多个过滤器,这些过滤器的执行顺序由各自提供的一个 int 值决定,提供的值越小则优先级越高,默认的过滤器及优先级如下: 自定义过滤器 在默认 ...
- linux tomcat jvm调优
修改TOMCAT_HOME/bin/catalina.sh文件: # OS specific support. $var _must_ be set to either true or false. ...
- VUE打包上线优化
1.将vue vue-router vuex 尽量使用CDN externals: { 'vue':'Vue', 'vue-router':'VueRouter', 'vuex':'Vuex', 'a ...
- Azure VMSS (3) 修改VM Template并创建VMSS
<Windows Azure Platform 系列文章目录> 在开始本章内容之前,我们需要准备好Azure VM的镜像,具体可以参考:Azure VMSS (2) 对VM执行Genera ...
- Hibernate复习
第一天 Hibernate是一个持久层的ORM框架.两个配置文件, 类名.hbm.xml类的属性和表的列对应 hibernate.cfg.xml核心配置文件 Hibernate相关API: Confi ...
- Python之Eric安装注意事项
处理该问题: http://www.knowsky.com/950133.html 注意缺乏的是qscintilla 双击install.py进行安装
- python之路——16
王二学习python的笔记以及记录,如有雷同,那也没事,欢迎交流,wx:wyb199594 学习内容 1.内置函数 1. python 数据类型:int bool 数据结构:dic list tupl ...
- Java异常学习总结二
异常的处理方式 方式一:捕获异常(try-catch-finally) 捕获异常是通过三个关键词来实现的:try-catch-finally.用try来执行一段程序,如果出现异常,系统抛出一个异常,可 ...
- 对窗体操作的WM消息
WM_CREATE 0x0001 应用程序创建一个窗口 WM_DESTROY 0x0002 一个窗口被销毁 WM_MOVE 0x0003 移动一个窗口 WM_SIZE 0x0005 改变一个窗口的大小 ...
- vlan划分
1.vlan:虚拟局域网: 作用:划分广播域,抑制广播风暴: 2.vlan技术的优点: 有效控制广播域范围: 增强局域网的安全性: 灵活构建虚拟工作组: 3.vlan划分的方式: 基于端口: 基于MA ...