Luogu 3119 [USACO15JAN]草鉴定Grass Cownoisseur
思路很乱,写个博客理一理。
缩点 + dp。
首先发现把一个环上的边反向是意义不大的,这样子不但不好算,而且相当于浪费了一次反向的机会。反正一个强连通分量里的点绕一遍都可以走到,所以我们缩点之后把一个强连通分量放在一起处理。
设$st$表示缩点之后$1$所在的点,设$f_{x}$表示从$st$走到$x$的最长链,$g_{x}$表示从$x$走到$st$的最长链,因为把一个$DAG$上的边反向一下并不会走重复的点,那么我们最后枚举一下边$(x, y)$,把它反向,这样子$f_{x} + g_{y} - siz_{st}$就可以成为备选答案,更新$ans$即可。
注意到有可能整个图强连通,所以$ans$应初始化为$siz_{st}$。
考虑一下$f$和$g$怎么求,一种想法是$st$开始的最长路,我们可以在反图和正图上分别跑一遍$spfa$,这样子可以通过,但是我并不清楚在$DAG$上$spfa$的表现是不是稳定的,另一种想法就是$dp$,直接记搜搞一搞,但是直接记搜是错误的,因为有一些点是不可能走到的,所以在$dp$之前要先$dfs$一遍标记出所有的合法点,然后再进行记搜即可。
时间复杂度$O(n)$。
放上写得很丑很长还可能有锅的代码。
你谷的数据是真的水。
Code:
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std; const int N = 1e5 + ; int n, m, tot = , head[N], dfsc = , dfn[N], low[N];
int scc = , f[N], g[N], inx[N], iny[N], top = , sta[N], bel[N], siz[N];
bool vis[N], ok[N];
vector <int> G1[N], G2[N]; struct Edge {
int to, nxt;
} e[N]; inline void add(int from, int to) {
e[++tot].to = to;
e[tot].nxt = head[from];
head[from] = tot;
} inline void read(int &X) {
X = ; char ch = ; int op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} inline int min(int x, int y) {
return x > y ? y : x;
} void tarjan(int x) {
low[x] = dfn[x] = ++dfsc;
vis[x] = , sta[++top] = x;
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(!dfn[y]) {
tarjan(y);
low[x] = min(low[x], low[y]);
} else if(vis[y])
low[x] = min(low[x], dfn[y]);
} if(low[x] == dfn[x]) {
++scc;
for(; sta[top + ] != x; --top) {
vis[sta[top]] = ;
siz[scc]++;
bel[sta[top]] = scc;
}
}
} inline void chkMax(int &x, int y) {
if(y > x) x = y;
} void dfs1(int x) {
ok[x] = , vis[x] = ;
for(unsigned int i = ; i < G1[x].size(); i++) {
int y = G1[x][i];
dfs1(y);
}
} int dp1(int x) {
if(vis[x]) return f[x];
vis[x] = ;
int res = ;
for(unsigned int i = ; i < G2[x].size(); i++) {
int y = G2[x][i];
if(ok[y]) chkMax(res, dp1(y));
}
f[x] = res + siz[x];
return f[x];
} void dfs2(int x) {
ok[x] = , vis[x] = ;
for(unsigned int i = ; i < G2[x].size(); i++) {
int y = G2[x][i];
dfs2(y);
}
} int dp2(int x) {
if(vis[x]) return g[x];
vis[x] = ;
int res = ;
for(unsigned int i = ; i < G1[x].size(); i++) {
int y = G1[x][i];
if(ok[y]) chkMax(res, dp2(y));
}
g[x] = res + siz[x];
return g[x];
} int main() {
// freopen("testdata.in", "r", stdin); read(n), read(m);
for(int i = ; i <= m; i++) {
read(inx[i]), read(iny[i]);
add(inx[i], iny[i]);
} for(int i = ; i <= n; i++)
if(!dfn[i]) tarjan(i); for(int i = ; i <= m; i++) {
if(bel[inx[i]] == bel[iny[i]]) continue;
G1[bel[inx[i]]].push_back(bel[iny[i]]);
G2[bel[iny[i]]].push_back(bel[inx[i]]);
} memset(vis, , sizeof(vis));
memset(ok, , sizeof(ok));
dfs1(bel[]); memset(vis, , sizeof(vis));
for(int i = ; i <= scc; i++) {
if(ok[i]) dp1(i);
} memset(vis, , sizeof(vis));
memset(ok, , sizeof(ok));
dfs2(bel[]); memset(vis, , sizeof(vis));
for(int i = ; i <= scc; i++) {
if(ok[i]) dp2(i);
} /* for(int i = 1; i <= scc; i++)
printf("%d ", g[i]);
printf("\n");
for(int i = 1; i <= scc; i++)
printf("%d ", f[i]);
printf("\n"); */ int ans = siz[bel[]];
for(int i = ; i <= m; i++) {
int u = bel[iny[i]], v = bel[inx[i]];
if(u == v) continue;
if(f[u] && g[v]) chkMax(ans, f[u] + g[v] - siz[bel[]]);
} printf("%d\n", ans);
return ;
}
Luogu 3119 [USACO15JAN]草鉴定Grass Cownoisseur的更多相关文章
- luogu P3119 [USACO15JAN]草鉴定Grass Cownoisseur
题目描述 In an effort to better manage the grazing patterns of his cows, Farmer John has installed one-w ...
- [Luogu P3119] [USACO15JAN]草鉴定Grass Cownoisseur (缩点+图上DP)
题面 传送门:https://www.luogu.org/problemnew/show/P3119 Solution 这题显然要先把缩点做了. 然后我们就可以考虑如何处理走反向边的问题. 像我这样的 ...
- 洛谷3119 [USACO15JAN]草鉴定Grass Cownoisseur
原题链接 显然一个强连通分量里所有草场都可以走到,所以先用\(tarjan\)找强连通并缩点. 对于缩点后的\(DAG\),先复制一张新图出来,然后对于原图中的每条边的终点向新图中该边对应的那条边的起 ...
- 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur 解题报告
P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 约翰有\(n\)块草场,编号1到\(n\),这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可 ...
- 洛谷——P3119 [USACO15JAN]草鉴定Grass Cownoisseur
P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 In an effort to better manage the grazing patterns of hi ...
- [USACO15JAN]草鉴定Grass Cownoisseur(分层图+tarjan)
[USACO15JAN]草鉴定Grass Cownoisseur 题目描述 In an effort to better manage the grazing patterns of his cows ...
- 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur (SCC缩点,SPFA最长路,枚举反边)
P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 In an effort to better manage the grazing patterns of hi ...
- 【洛谷P3119】[USACO15JAN]草鉴定Grass Cownoisseur
草鉴定Grass Cownoisseur 题目链接 约翰有n块草场,编号1到n,这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可能多的草场去品尝牧草. 贝西总是从1号草场出发,最后 ...
- 洛谷—— P3119 [USACO15JAN]草鉴定Grass Cownoisseur || BZOJ——T 3887: [Usaco2015 Jan]Grass Cownoisseur
http://www.lydsy.com/JudgeOnline/problem.php?id=3887|| https://www.luogu.org/problem/show?pid=3119 D ...
随机推荐
- VMwear安装Centos7超详细过程
本篇文章主要介绍了VMware安装Centos7超详细过程(图文),具有一定的参考价值,感兴趣的小伙伴们可以参考一下 1.软硬件准备 软件:推荐使用VMwear,我用的是VMwear 12 镜像:Ce ...
- zabbix 利用python脚本实现短信告警
一.编写脚本 cd /usr/local/zabbix-4.0.3/share/zabbix/alertscripts vi zabbix_sms.py 内容如下: #!/usr/bin/python ...
- python学习 day19 configparser模块 os模块 subprocess模块
上周五回顾 logging 用于记录日志 四种核心角色: 生成器Logger 过滤器Filter 处理器Handler 格式化处理器 Formatter logging.info.debug 使用默认 ...
- python 遍历enumerate
在python中enumerate的用法多用于在for循环中得到计数,本文即以实例形式向大家展现python中enumerate的用法.具体如下: enumerate参数为可遍历的变量,如 字符串,列 ...
- c#实现动态加载Dll(转)
c#实现动态加载Dll 分类: .net2009-12-28 13:54 3652人阅读 评论(1) 收藏 举报 dllc#assemblynullexceptionclass 原理如下: 1.利用反 ...
- VHS介绍
Java.JS HTTP流传输(VHS)介绍“我怎么才能让我的视频和Video.js一起玩?”“ 这是我们在使用Vio.js时最常见的问题之一.这是个好问题. 如果有人检查了Vo.js的拷贝,他们的内 ...
- 测试--错误java.lang.Exception: No tests found matching [{ExactMatcher:fDisplayName=select], {ExactMatcher:fDisplayName=select(com.rjj.demo.DemoApplicationTests)]...
异常这个错误java.lang.Exception: No tests found matching [{ExactMatcher:fDisplayName=select], {ExactMatche ...
- java日期加减年月日
/** * 日期相加减 * @param time * 时间字符串 yyyy-MM-dd HH:mm:ss * @param num * 加的数,-num就是减去 * @return * 减去相应的数 ...
- Docker基础入门
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会有任何 ...
- python之栈和队列
1. 栈 1.1 示例 #!/usr/bin/env python # -*- codinfg:utf-8 -*- ''' @author: Jeff LEE @file: .py @time: 20 ...