题目:

给一个有向图,然后选一条路径起点终点都为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的更多相关文章

  1. BZOJ 3887: [Usaco2015 Jan]Grass Cownoisseur tarjan + spfa

    Code: #include <bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) ...

  2. [Usaco2015 Jan]Grass Cownoisseur Tarjan缩点+SPFA

    考试的时候忘了缩点,人为dfs模拟缩点,没想到竟然跑了30分,RB爆发... 边是可以重复走的,所以在同一个强连通分量里,无论从那个点进入从哪个点出,所有的点一定能被一条路走到. 要使用缩点. 然后我 ...

  3. 【BZOJ3887】【Usaco2015 Jan】Grass Cownoisseur Tarjan+Spfa

    我们可以看出这个东西可以缩点成DAG,因为我们在所称的点里用特技的话,要么没用,要么削弱自己对点的收割能力与边的联通权,所以我们缩完点之后在图上枚举反向的变,因为我们只可能反向一条边,而且我们知道在这 ...

  4. BZOJ3887 [Usaco2015 Jan] Grass Cownoisseur 【tarjan】【DP】*

    BZOJ3887 [Usaco2015 Jan] Grass Cownoisseur Description In an effort to better manage the grazing pat ...

  5. [USACO15JAN]草鉴定Grass Cownoisseur(分层图+tarjan)

    [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 In an effort to better manage the grazing patterns of his cows ...

  6. [补档][Usaco2015 Jan]Grass Cownoisseur

    [Usaco2015 Jan]Grass Cownoisseur 题目 给一个有向图,然后选一条路径起点终点都为1的路径出来,有一次机会可以沿某条边逆方向走,问最多有多少个点可以被经过? (一个点在路 ...

  7. 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur 解题报告

    P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 约翰有\(n\)块草场,编号1到\(n\),这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可 ...

  8. 【洛谷P3119】[USACO15JAN]草鉴定Grass Cownoisseur

    草鉴定Grass Cownoisseur 题目链接 约翰有n块草场,编号1到n,这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可能多的草场去品尝牧草. 贝西总是从1号草场出发,最后 ...

  9. bzoj3887: [Usaco2015 Jan]Grass Cownoisseur

    题意: 给一个有向图,然后选一条路径起点终点都为1的路径出来,有一次机会可以沿某条边逆方向走,问最多有多少个点可以被经过?(一个点在路径中无论出现多少正整数次对答案的贡献均为1) =>有向图我们 ...

随机推荐

  1. loadrunner脚本篇——Run-time Settings之ContentCheck

    运用场景(很少用到): ContentCheck的设置可用来让VuGen检测存在错误的站点页面.如果被测的Web应用没有使用自定义的错误页面,那么这里不用添加规则,因为LR在回放时候,可以默认的捕捉到 ...

  2. bex5部署后不更新

    哪个模块没更新,就编译哪个模块 在x5/tools/compile下,运行对应模块的bat,并清空浏览器缓存 如果修改了.w文件,也可以删除相应的.catch文件夹 和.release文件夹,并且注意 ...

  3. jstl-functions标签

    比如需要再jstl中定义一个String类型的数组 <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl ...

  4. HTTP协议—常见的HTTP响应状态码解析

    常见的HTTP响应状态码解析 1XX Informational(信息性状态码) 2XX Success(成功状态码) 3XX Redirection(重定向状态码) 4XX Client Error ...

  5. nodejs爬虫selenium

    6.元素操作 查找元素 使用操作如何找到页面元素Webdriver的findElement方法可以用来找到页面的某个元素,最常用的方法是用id和name查找.下面介绍几种比较常用的方法. By ID假 ...

  6. iOS_AFNetWorking框架分析

    网络 — 你的程序离开了它就不能生存下去!苹果的Foundation framework中的NSURLConnection又非常难以理解, 不过这里有一个可以使用的替代品:AFNetworking.A ...

  7. linux下pycharm的使用

    百度搜索pycharm 然后打开pycharm的官网 然后在官网首页点击down   如果使用的是Linux系统,那么默认已经选择Linux版本 左边的down是全功能的IDE和WEB扩展,属于商业版 ...

  8. 【P1714】切蛋糕(单调队列)

    实在不明白难度等级,难不成前缀和是个很变态的东西? 说白了就是单调队列裸题,都没加什么别的东西,就是一个前缀和的计算,然而这个题也不是要用它优化,而是必须这么做啊. #include<iostr ...

  9. PAT1022. Digital Library (30)

    两个坑. 一个是一直用的malloc不行了.因为malloc分配的是固定大小,之前做的题没遇到过是因为一般string都不长(malloc分配string为24个Byte),这次直接报段错误,呢们了半 ...

  10. Gerrit使用感受

    CodeReivew好工具,可以随业务需求灵活配置权限等.