题目

草鉴定,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. PAT-1030 Travel Plan (30 分) 最短路最小边权 堆优化dijkstra+DFS

    PAT 1030 最短路最小边权 堆优化dijkstra+DFS 1030 Travel Plan (30 分) A traveler's map gives the distances betwee ...

  2. SQL Server的非聚集索引中会存储NULL吗?

    原文:SQL Server的非聚集索引中会存储NULL吗? SQL Server的非聚集索引中会存储NULL吗? 这是个很有意思的问题,下面通过如下的代码,来说明,到底会不会存储NULL. --1.建 ...

  3. Tomcat Lifecycle

    org.apache.catalina.Lifecycle 接口统一管理生命周期,所有生命周期组件都要实现Lifecycle接口. 该接口定义了13个String类型的常量,用于LifecycleEv ...

  4. VBA Excel对象(十九)

    使用VBA进行编程时,用户将要处理的重要对象很少.下面是一些常见的对象 - 应用程序对象 工作簿对象 工作表对象 范围对象 应用程序对象 应用程序对象由以下部分组成 - 应用程序范围的设置和选项. 返 ...

  5. SAP-参数(条件表)配置教程–GS01/GS02/GS03

    转载:http://www.baidusap.com/abap/others/2849 在SAP开发中,某段代码运行可能需要满足某个条件,通常解决办法有两种:一种是在代码中写死限制条件,此种方式当限制 ...

  6. DBShop后台RCE之曲线救国

    本文最早发布在朋友的公众号 黑客信徒 中,文章是自己写的 不存在抄袭  特此申明 --------------------- 前言 DBShop是一款基于ZendFramework2框架的电子商务系统 ...

  7. 【OF框架】缓存Session/Cookies/Cache代码调用api,切换缓存到Redis

    准备 缓存服务在应用开发中最常用的功能,特别是Session和Cookies,Cache部分业务开发过程会使用到. 在负载均衡环境下,缓存服务需要存储到服务器. 缓存默认实现在内存在,可以通过配置切换 ...

  8. nginx配置文件详解【nginx.conf】

    #基本配置: #user nobody;#配置worker进程运行用户worker_processes 1;#配置工作进程数目,根据硬件调整.通常等于CPU数量或者2倍于CPU数量 比如四核电脑(可以 ...

  9. 浅谈Java中的AOP面向切面的变成和控制反转IOC

    https://blog.csdn.net/hi_kevin/article/details/7325554 https://www.cnblogs.com/zedosu/p/6632260.html ...

  10. Robot Framework--接口实例一

    需求:api/car/detail/recommendcar.json   接口返回的车辆数量少于等于20且车辆不能重复 分析:统计接口中返回的列表的长度,再把carid拿出来组成一个新的列表,判断这 ...