bzoj 3887: Grass Cownoisseur Tarjan+Topusort
题目:
给一个有向图,然后选一条路径起点终点都为1的路径出来,有一次机会可以沿某条边逆方向走,问最多有多少个点可以被经过?(一个点在路径中无论出现多少正整数次对答案的贡献均为1)
题解:
首先考虑简单一些的问题
如果没有逆向的机会,那么\(ans\)即为\(1\)所在的强连通分量的大小。
但是现在有一个逆向的机会
如果我们将缩点后的\(DAG\)搞出来的话就可以发现:
一定是从\(1\)的连通块出发走到别的地方然后通过走逆向边返回一个可以到达\(1\)的路径上。
那么我们可以预处理每个点到根的最大\(siz\)之和根到每个点的路上的最大\(siz\)之和。
然后枚举每条边进行\(O(1)\)判断即可.
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
#define rg register int
#define rep(i,a,b) for(rg i=(a);i<=(b);++i)
#define per(i,a,b) for(rg i=(a);i>=(b);--i)
const int maxn = 100010;
struct Edge{
int to,next;
}G[maxn];
int head[maxn],cnt;
void add(int u,int v){
G[++cnt].to = v;
G[cnt].next = head[u];
head[u] = cnt;
}
int dfn[maxn],low[maxn],dfs_clock;
int sta[maxn],top,belong[maxn];
int scc_cnt,siz[maxn];
#define v G[i].to
void dfs(int u){
dfn[u] = low[u] = ++ dfs_clock;
sta[++top] = u;
for(rg i = head[u];i;i=G[i].next){
if(!dfn[v]){
dfs(v);
low[u] = min(low[u],low[v]);
}else if(!belong[v]) low[u] = min(low[u],dfn[v]);
}
if(dfn[u] == low[u]){
++ scc_cnt;
while(1){
int x = sta[top--];
belong[x] = scc_cnt;
siz[scc_cnt] ++ ;
if(x == u) break;
}
}
}
#undef v
struct Topu{
struct Edge{
int to,next;
}G[maxn];
int head[maxn],cnt,deg[maxn];
void add(int u,int v){
G[++cnt].to = v;
G[cnt].next = head[u];
head[u] = cnt;
++ deg[v];
}
#define v G[i].to
int q[maxn],l,r,f[maxn];
void bfs(){
memset(f,-0x3f,sizeof f);
f[belong[1]] = siz[belong[1]];l = 0;r = -1;
rep(i,1,scc_cnt){
if(deg[i] == 0) q[++r] = i;
}
while(l <= r){
int u = q[l++];
for(rg i = head[u];i;i=G[i].next){
f[v] = max(f[v],f[u] + siz[v]);
if(-- deg[v] == 0) q[++r] = v;
}
}return ;
}
#undef v
}a,b;
struct Node{
int u,v;
}e[maxn];
int main(){
int n,m;read(n);read(m);
int u,v;
rep(i,1,m){
read(u);read(v);
e[i].u = u;e[i].v = v;
add(u,v);
}
rep(i,1,n) if(!dfn[i]) dfs(i);
rep(i,1,m){
if(belong[e[i].u] == belong[e[i].v]) continue;
a.add(belong[e[i].u],belong[e[i].v]);
b.add(belong[e[i].v],belong[e[i].u]);
}a.bfs();b.bfs();
int ans = siz[belong[1]] << 1;
rep(i,1,m){
if(belong[e[i].u] == belong[e[i].v]) continue;
ans = max(ans,a.f[belong[e[i].v]] + b.f[belong[e[i].u]]);
}
printf("%d\n",ans - siz[belong[1]]);
return 0;
}
bzoj 3887: Grass Cownoisseur Tarjan+Topusort的更多相关文章
- BZOJ 3887: [Usaco2015 Jan]Grass Cownoisseur tarjan + spfa
Code: #include <bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) ...
- [Usaco2015 Jan]Grass Cownoisseur Tarjan缩点+SPFA
考试的时候忘了缩点,人为dfs模拟缩点,没想到竟然跑了30分,RB爆发... 边是可以重复走的,所以在同一个强连通分量里,无论从那个点进入从哪个点出,所有的点一定能被一条路走到. 要使用缩点. 然后我 ...
- 【BZOJ3887】【Usaco2015 Jan】Grass Cownoisseur Tarjan+Spfa
我们可以看出这个东西可以缩点成DAG,因为我们在所称的点里用特技的话,要么没用,要么削弱自己对点的收割能力与边的联通权,所以我们缩完点之后在图上枚举反向的变,因为我们只可能反向一条边,而且我们知道在这 ...
- BZOJ3887 [Usaco2015 Jan] Grass Cownoisseur 【tarjan】【DP】*
BZOJ3887 [Usaco2015 Jan] Grass Cownoisseur Description In an effort to better manage the grazing pat ...
- [USACO15JAN]草鉴定Grass Cownoisseur(分层图+tarjan)
[USACO15JAN]草鉴定Grass Cownoisseur 题目描述 In an effort to better manage the grazing patterns of his cows ...
- [补档][Usaco2015 Jan]Grass Cownoisseur
[Usaco2015 Jan]Grass Cownoisseur 题目 给一个有向图,然后选一条路径起点终点都为1的路径出来,有一次机会可以沿某条边逆方向走,问最多有多少个点可以被经过? (一个点在路 ...
- 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur 解题报告
P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 约翰有\(n\)块草场,编号1到\(n\),这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可 ...
- 【洛谷P3119】[USACO15JAN]草鉴定Grass Cownoisseur
草鉴定Grass Cownoisseur 题目链接 约翰有n块草场,编号1到n,这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可能多的草场去品尝牧草. 贝西总是从1号草场出发,最后 ...
- bzoj3887: [Usaco2015 Jan]Grass Cownoisseur
题意: 给一个有向图,然后选一条路径起点终点都为1的路径出来,有一次机会可以沿某条边逆方向走,问最多有多少个点可以被经过?(一个点在路径中无论出现多少正整数次对答案的贡献均为1) =>有向图我们 ...
随机推荐
- predis操作大全
predis是php连接redis的操作库,由于它完全使用php编写,大量使用命名空间以及闭包等功能,只支持php5.3以上版本,故实测性能一般,每秒25000次读写,相信改换c语言编写的php扩展后 ...
- HTML系列(3)基本的HTML标签(二)
本节继续介绍HTML的常用标签. (1)input标签之文本域(text和textarea).密码域(password): <!DOCTYPE html> <html ...
- java WordUtils word文档工具类
package com.sicdt.library.core.utils; import java.io.ByteArrayOutputStream; import java.io.IOExcepti ...
- 快乐学习 Ionic Framework+PhoneGap 手册1-3 {面板切换}
编程的快乐和乐趣,来自于能成功运行程序并运用到项目中,会在后面案例,实际运用到项目当中与数据更新一起说明 从面板切换开始,请看效果图和代码,这只是一个面板切换的效果 Index HTML Code & ...
- 逐行读取txt文件并存入到数组中
get_file_contents_on_line.php $file = fopen("log.txt", "r"); $user=array(); $i=0 ...
- Go 模板语法
Sprig the useful template functions for Go templates (http://masterminds.github.io/sprig/) Github - ...
- 搭建TXManager分布式事务协调者
事务分组id 缓存到redis 需要配置连接到自己的 redis地址 启动后:
- 集成Spring web.xml配置总结
1.web.xml 的加载顺序是:ServletContext -> context-param -> listener -> filter -> servlet 1.serv ...
- jsp 内置对象---EL
ServletRequest : java.lang.String getParameter(java.lang.String name) 返回一个string 对应 n ...
- form组件的总结
1.form组件(******) 局部钩子 全局钩子 ''' 实例化时: self.fields={ "username":"字段规则对象", "pa ...