题目:

给一个有向图,然后选一条路径起点终点都为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. springboot——数据层访问搭建 集成Duid连接池

    springboot中默认是使用的tomcat的连接池,如果我们想要第三方的连接池,我们这么配置呢? 首先在application.yml文件中注释掉之前数据库的配置,重新用druid的方式配置: # ...

  2. 【HackerRank】Find the Median(Partition找到数组中位数)

    In the Quicksort challenges, you sorted an entire array. Sometimes, you just need specific informati ...

  3. hi3515 rtc驱动(ds1307/1339)驱动和示例

    将驱动放入/extdrv中编译 部分驱动如下: #include <linux/module.h> #include <linux/miscdevice.h>#include ...

  4. VCS 常用命令速查

      VCS是编译型Verilog模拟器,它完全支持OVI标准的Verilog HDL语言.PLI和SDF.VCS具有目前行业中最高的模拟性能,其出色的内存管理能力足以支持千万门级的ASIC设计,而其模 ...

  5. 发现一个小坑的地方,unity的协程,想要停止,必须以字符串启动

    今天想要停止一个协成,发现调用 StopCoroutine(ShowDebug()); 竟然不管用,后来看了文档才知道,原来想要停止协成,必须用字符启动协程 StartCoroutine(" ...

  6. EXP-00008:遇到ORACLE错误904问题

    案例情景--在一次Oracle 数据库导出时: C:\Documents and Settings\Administrator>exp lsxy/lsxy@lsxy_db file=E:\lsx ...

  7. Idea根据表自动生成实体

    Idea根据表自动生成实体: 首先说下这种方式有个缺点,就是如果表里面有日期.时间类型,那么需要手动的设置映射类型 第一步:在Idea中配置好数据库: 在Idea窗口右边,点击Database按钮 配 ...

  8. 16个tomcat面试题

    1)解释什么是Jasper? Jasper是Tomcat的JSP引擎 它解析JSP文件,将它们编译成JAVA代码作为servlet 在运行时,Jasper允许自动检测JSP文件的更改并重新编译它们 2 ...

  9. mac下安装py第三方库到python3下

    python3 -m pip install **** 中间可能碰到超时问题 python3 pip --default-timeout=100 install -U **** 设置默认超时时间即可 ...

  10. jQuery计时器插件

    /** * 定义一个jQuery计时插件,实现记录计时开始时间.结束时间,总共耗时的功能 * @param $ * * @author Ivan 2862099249@qq.com * @date 2 ...