题目

草鉴定,tarjan可以用来缩点,优化spfa的时间,

缩点之后就是一个\(DAG\)了,因此完全可以用来跑spfa上的最长路,然后枚举每条边,查看是否这条边的两个节点分别可以到达起点所在的强连通分量。(因为要返回到1点)。然后更新答案就可以了。

可是为什么要缩点呢,因为只能逆行一次,逆行之后通过在强连通分量上的点可以把强连通分量上的所有点全都遍历一次,最后还可以回到强连通分量上的起点,所以可以tarjan缩点。

#include <bits/stdc++.h>
using namespace std;
int n, m, lin[100010], lne[100100], lf[101000], dfn[100010], low[100100], vis[100100], belong[100100], dis[1001000], dis2[101000], color, tot, cnt, ans, cntne, cntf;
stack <int> s;
int sum[100100];struct edg {
int to, nex;
}e[1000100], f[1000100], ne[100100];
inline void add(int u, int v)
{
e[++cnt].to = v;
e[cnt].nex = lin[u];
lin[u] = cnt;
}
inline void add2(int u, int v)
{
ne[++cntne].to = v;
ne[cntne].nex = lne[u];
lne[u] = cntne;
}
inline void addf(int u, int v)
{
f[++cntf].to = v;
f[cntf].nex = lf[u];
lf[u] = cntf;
}
inline void tarjan(int u)
{
dfn[u] = low[u] = ++tot;
s.push(u); vis[u] = 1;
for(int i = lin[u]; i; i = e[i].nex)
{
int v = e[i].to;
if(!dfn[v]) {
tarjan(v);
low[u] = min(low[u],low[v]);
}
else if(vis[v]) low[u] = min(low[u],dfn[v]);
}
if(low[u] == dfn[u])
{
int v = -3;
color++;
do
{
v = s.top(); s.pop();
belong[v] = color;
vis[v] = 0;
sum[color]++;
} while (u != v);
}
}
int inq[101000];
inline void spfa()
{
memset(dis, -123, sizeof(dis));
queue <int> q;
dis[belong[1]] = sum[belong[1]];
q.push(belong[1]);
while (!q.empty())
{
int cur = q.front(); q.pop(); inq[cur] = 0;
for (int i = lne[cur]; i; i = ne[i].nex)
{
int to = ne[i].to;
if (dis[cur] + sum[to] > dis[to])
{
dis[to] = dis[cur] + sum[to];
if (!inq[to])
inq[to] = 1, q.push(to);
}
}
}
}
inline void sf()
{
memset(dis2, -123, sizeof(dis2));
queue <int> q;
// memset(vis, 0, sizeof(vis));
dis2[belong[1]] = sum[belong[1]]; q.push(belong[1]);
while (!q.empty())
{
int cur = q.front(); q.pop(); inq[cur] = 0;
for (int i = lf[cur]; i; i = f[i].nex)
{
int to = f[i].to;
if(dis2[cur] + sum[to] > dis2[to])
{
dis2[to] = dis2[cur] + sum[to];
if (!inq[to])
inq[to] = 1, q.push(to);
}
}
}
}
int b1[100100], b2[101000];
void dfs1(int u)
{
b1[u] = 1;
for (int i = lne[u]; i; i = ne[i].nex)
if (!b1[ne[i].to])
dfs1(ne[i].to);
}
void dfs2(int u)
{
b2[u] = 1;
for (int i = lf[u]; i; i = f[i].nex)
if (!b2[f[i].to])
dfs2(f[i].to);
}
inline void init()
{
scanf("%d%d", &n, &m);
for (int i = 1, u, v; i <= m; i++)
scanf("%d%d", &u, &v), add(u, v);
for (int i = 1; i <= n; i++)
if (!dfn[i]) tarjan(i); }
inline void jiantu()
{
for (int i = 1; i <= n; i++)
for (int j = lin[i]; j; j = e[j].nex)
{
int to = e[j].to;
if (belong[i] != belong[to]) add2(belong[i], belong[to]), addf(belong[to], belong[i]);
}
}
int main()
{
init();
jiantu();
dfs1(belong[1]);
dfs2(belong[1]);
spfa();
sf();
for (int i = 1; i <= color; i++)
if (b1[i])
for (int j = lf[i]; j; j = f[j].nex)
if (b2[f[j].to])
ans = max(ans, dis2[f[j].to] + dis[i]);
ans -= sum[belong[1]];
printf("%d\n", ans);
return 0;
}

洛谷P3119草鉴定的更多相关文章

  1. 洛谷P3119 草鉴定

    这个题调了一天.. 传送门 读完题目之后我们不难想出这个题是个tarjan缩点问题,因为尽量多的经过草场,所以一号点所在的强连通分量里左右的点都是不需要在进行走逆向边,所能到达的. 然后问题就落在怎么 ...

  2. 洛谷3119 草鉴定(tarjan)

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

  3. 【题解】洛谷P3119 Grass Cownoisseur G

    题面:洛谷P3119 Grass Cownoisseur G 本人最近在熟悉Tarjan的题,刷了几道蓝题后,我飘了 趾高气扬地点开这道紫题,我一瞅: 哎呦!这不是分层图吗? 突然就更飘了~~~ 用时 ...

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

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

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

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

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

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

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

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

  8. 洛谷P3119 USACO15JAN 草鉴定

    题目描述 In an effort to better manage the grazing patterns of his cows, Farmer John has installed one-w ...

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

    屠龙宝刀点击就送 Tarjan缩点+拓扑排序 以后缩点后建图看n范围用vector ,或者直接用map+vector 结构体里数据要清空 代码: #include <cstring> #i ...

随机推荐

  1. Springboot对JPA的支持及使用

    目的: 1.springboot之jpa支持 2.Springboot+bootstrap界面版之增删改查及图片上传 springboot之jpa支持 导入相关pom依赖 <dependency ...

  2. shell 学习笔记3-shell变量扩展

    一.特殊位置参数变量 1.特殊位置参数变量 在shell中比如:$0.$1.$#,等被称为特殊位置参数变量,当命令行.函数.脚本执行等处传递参数时,就需要使用位置参数变量 参数说明如下: 2.示例$1 ...

  3. Spring Cloud Alibaba学习笔记(10) - Spring消息编程模型下,使用RocketMQ收发消息

    编写生产者 集成 添加依赖 <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId&g ...

  4. springboot + shiro 构建权限模块

    权限模块基本流程 权限模块的基本流程:用户申请账号和权限 -->登陆认证 -->安全管控模块认证 -->调用具体权限模块(基于角色的权限控制) --> 登陆成功 -->访 ...

  5. ABP 基于DDD的.NET开发框架 学习(二)创建实体

    1.创建模型类打开.Core项目,新建新建一个项目文件夹(Demo);为了演示表关联及外键的使用,创建两个类:创建类ClothesCategoty.csusing Abp.Domain.Entitie ...

  6. 图片上传怎么用File接受文件

    xl_echo编辑整理,欢迎转载,转载请声明文章来源.欢迎添加echo微信(微信号:t2421499075)交流学习. 百战不败,依不自称常胜,百败不颓,依能奋力前行.——这才是真正的堪称强大!! - ...

  7. python简单页面爬虫入门 BeautifulSoup实现

    本文可快速搭建爬虫环境,并实现简单页面解析 1.安装 python 下载地址:https://www.python.org/downloads/ 选择对应版本,常用版本有2.7.3.4 安装后,将安装 ...

  8. JS中浏览器的数据存储机制

    一.JS中的三种数据存储方式 cookie.sessionStorage.localStorage 二.cookie 1.cookie的定义: cookie是存储在浏览器上的一小段数据,用来记录某些当 ...

  9. 如何让类数组也使用数组的方法比如:forEach()

    思路: 让类数组绑定数组的方法<div>1</div><div>2</div>方法一: let div = document.getElementsBy ...

  10. iOS 中 UIView 和 CALayer 的关系

    UIView 有一个名叫 layer ,类型为 CALayer 的对象属性,它们的行为很相似,主要区别在于:CALayer 继承自 NSObject ,不能够响应事件. 这是因为 UIView 除了负 ...