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的更多相关文章

  1. luogu3119/bzoj3887 草鉴定 (tarjan缩点+spfa)

    首先缩一波点,就变成了一个DAG,边权是出点的大小 那我们走到某个点的时候可能会有两种状态:已经走过反边或者没走过 于是就把一个点拆成两层(x和x+N),第二层的点表示我已经走过反边了,每层中的边和原 ...

  2. 洛谷3119 草鉴定(tarjan)

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

  3. luogu3119 草鉴定

    题目大意 给出一个有向图,问将图中的哪一个边翻转,会使节点1所在的强连通分量内的节点数最多.输出这个节点数. 题解 让我们看看暴力怎么做,即枚举每一条边,将其翻转,然后求节点1所在强连通分量节点数,然 ...

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

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

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

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

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

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

  7. 洛谷——P3119 [USACO15JAN]草鉴定Grass Cownoisseur

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

  8. 洛谷P3119草鉴定

    题目 草鉴定,tarjan可以用来缩点,优化spfa的时间, 缩点之后就是一个\(DAG\)了,因此完全可以用来跑spfa上的最长路,然后枚举每条边,查看是否这条边的两个节点分别可以到达起点所在的强连 ...

  9. 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur (SCC缩点,SPFA最长路,枚举反边)

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

随机推荐

  1. nginx配置http强制跳转https

    nginx配置http强制跳转https 网站添加了https证书后,当http方式访问网站时就会报404错误,所以需要做http到https的强制跳转设置. 一.采用nginx的rewrite方法 ...

  2. 【java】类的继承

    继承:特殊类拥有一般类的全部属性与行为. 继承好处:1.提高了代码的复用性2.让类与类之前产生了关系,有了这个关系才有多态的特性.继承是类和类之前的关系. 注意事项: 1.java只支持单继承,不支持 ...

  3. c# 动态绘制直线和曲线

    c# 动态绘制直线和曲线   在本案例中利用Graphics对象动态地绘制直线和曲线.程序运行后,选择“直线”单选按钮,然后按下鼠标左键拖动鼠标就可以绘制直线,选择“曲线”单选按钮,然后移动鼠标就可以 ...

  4. react高阶组件

    高阶组件 为了提高组件复用性,在react中就有了HOC(Higher-Order Component)的概念.所谓的高阶组件,其本质依旧是组件,只是它返回另外一个组件,产生新的组件可以对属性进行包装 ...

  5. Filedset

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. Go的CSP并发模型实现:M, P, G

    最近抽空研究.整理了一下Golang调度机制,学习了其他大牛的文章.把自己的理解写下来.如有错误,请指正!!! golang的goroutine机制有点像线程池:        一.go 内部有三个对 ...

  7. 使用redis-cli --pipe快速插入数据

    具体实现步骤如下:(参考http://www.cnblogs.com/ivictor/p/5446503.html) 1. 新建一个文本文件redis_commands.txt,包含redis命令 S ...

  8. 面试回顾——List<T>排序

    1.如何对List<T>排序: public static void main(String[] args) { Student stu1=new Student("张三&quo ...

  9. 获取电脑的 SN 码

    wmic bios get serialnumber

  10. __iter__ 和 __next__

    class F: def __init__(self,x): self.x = x def __iter__(self): #把对象 变成可迭代对象 return self def __next__( ...