题目描述

In an effort to better manage the grazing patterns of his cows, Farmer John has installed one-way cow paths all over his farm. The farm consists of N fields, conveniently numbered 1..N, with each one-way cow path connecting a pair of fields. For example, if a path connects from field X to field Y, then cows are allowed to travel from X to Y but not from Y to X.

Bessie the cow, as we all know, enjoys eating grass from as many fields as possible. She always starts in field 1 at the beginning of the day and visits a sequence of fields, returning to field 1 at the end of the day. She tries to maximize the number of distinct fields along her route, since she gets to eat the grass in each one (if she visits a field multiple times, she only eats the grass there once).

As one might imagine, Bessie is not particularly happy about the one-way restriction on FJ's paths, since this will likely reduce the number of distinct fields she can possibly visit along her daily route. She wonders how much grass she will be able to eat if she breaks the rules and follows up to one path in the wrong direction. Please compute the maximum number of distinct fields she can visit along a route starting and ending at field 1, where she can follow up to one path along the route in the wrong direction. Bessie can only travel backwards at most once in her journey. In particular, she cannot even take the same path backwards twice.

约翰有n块草场,编号1到n,这些草场由若干条单行道相连。奶牛贝西是美味牧草的鉴赏家,她想到达尽可能多的草场去品尝牧草。

贝西总是从1号草场出发,最后回到1号草场。她想经过尽可能多的草场,贝西在通一个草场只吃一次草,所以一个草场可以经过多次。因为草场是单行道连接,这给贝西的品鉴工作带来了很大的不便,贝西想偷偷逆向行走一次,但最多只能有一次逆行。问,贝西最多能吃到多少个草场的牧草。

输入输出格式

输入格式:

INPUT: (file grass.in)

The first line of input contains N and M, giving the number of fields and the number of one-way paths (1 <= N, M <= 100,000).

The following M lines each describe a one-way cow path. Each line contains two distinct field numbers X and Y, corresponding to a cow path from X to Y. The same cow path will never appear more than once.

输出格式:

OUTPUT: (file grass.out)

A single line indicating the maximum number of distinct fields Bessie

can visit along a route starting and ending at field 1, given that she can

follow at most one path along this route in the wrong direction.

输入输出样例

输入样例#1: 复制

7 10
1 2
3 1
2 5
2 4
3 7
3 5
3 6
6 5
7 2
4 7
输出样例#1: 复制

6

说明

SOLUTION NOTES:

Here is an ASCII drawing of the sample input:

v---3-->6

7 |\ |

^\ v \ |

| \ 1 | | | v | v 5

4<--2---^

Bessie can visit pastures 1, 2, 4, 7, 2, 5, 3, 1 by traveling

backwards on the path between 5 and 3. When she arrives at 3 she

cannot reach 6 without following another backwards path.

1A爽,缩点后变成一棵树,spfa处理出树上每个点到1所在点的最长路,然后枚举连向点1和点1连向的点之间的边,答案就是这两个点最长路的和

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = ;
inline int read() {
int x=,f=;
char c=getchar();
while(c<''||c>'') {
if(c=='-')f=-;
c=getchar();
}
while(c<=''&&c>='') {
x=x*+c-'';
c=getchar();
}
return x*f;
}
int n,m;
struct node{
int v,next;
}edge[maxn],E1[maxn],E2[maxn];
int head[maxn],H1[maxn],H2[maxn],num,N1,N2;
void add_edge(int x,int y) {
edge[++num].v=y;edge[num].next=head[x];head[x]=num;
}
void A1(int x,int y) {
E1[++N1].v=y;E1[N1].next=H1[x];H1[x]=N1;
}
void A2(int x,int y){
E2[++N2].v=y;E2[N2].next=H2[x];H2[x]=N2;
}
int dfn[maxn],low[maxn],tn=,stack[maxn],color[maxn],color_cnt;
int top=,cnt[maxn];bool vis[maxn];
void tarjan(int x) {
dfn[x]=low[x]=++tn;stack[++top]=x,vis[x]=;
for(int i=head[x];i;i=edge[i].next) {
int v=edge[i].v;
if(!dfn[v]) {
tarjan(v);
low[x]=min(low[x],low[v]);
}
else if(vis[v]) low[x]=min(low[x],dfn[v]);
}
if(dfn[x]==low[x]) {
++color_cnt;
while(stack[top]!=x) {
vis[stack[top]]=;
color[stack[top]]=color_cnt;
top--;
cnt[color_cnt]++;
}
cnt[color_cnt]++;
color[x]=color_cnt;vis[x]=;top--;
}
}
int dis1[maxn],dis2[maxn];
int que[maxn*];
bool can[maxn],can2[maxn];
void topo1(int S) {
int h=,t=;
que[]=S;
dis1[S]=cnt[S];
memset(vis,,sizeof vis);
vis[S]=;can[S]=;
while(h<=t) {
int u=que[h++];
for(int i=H1[u];i;i=E1[i].next) {
int v=E1[i].v;can[v]=;
if(dis1[v]<dis1[u]+cnt[v]) {
dis1[v]=max(dis1[v],dis1[u]+cnt[v]);
if(!vis[v])que[++t]=v,vis[v]=;
}
}
vis[u]=;
}
}
void topo2(int S) {
int h=,t=;
que[]=S;
dis2[S]=cnt[S];
memset(vis,,sizeof vis);
vis[S]=;can2[S]=;
while(h<=t) {
int u=que[h++];
for(int i=H2[u];i;i=E2[i].next) {
int v=E2[i].v;can2[v]=;
if(dis2[v]<dis2[u]+cnt[v]) {
dis2[v]=max(dis2[v],dis2[u]+cnt[v]);
if(!vis[v])que[++t]=v,vis[v]=;
}
}
vis[u]=;
}
}
int main() {
n=read(),m=read();
for(int a,b,i=;i<=m;++i) {
a=read(),b=read();
add_edge(a,b);
}
for(int i=;i<=n;++i)
if(!dfn[i])tarjan(i);
int S=color[];
for(int i=;i<=n;++i) {
for(int j=head[i];j;j=edge[j].next) {
int v=edge[j].v;
if(color[v]!=color[i]){
A1(color[i],color[v]);
A2(color[v],color[i]);
}
}
}
topo1(color[]);
topo2(color[]);
int ans=;
for(int i=;i<=color_cnt;++i) {
for(int j=H1[i];j;j=E1[j].next) {
int v=E1[j].v;
if(can2[i]&&can[v]) {
ans=max(ans,dis2[i]+dis1[v]-cnt[color[]]);
}
}
}
printf("%d\n",ans);
return ;
}

luogu P3119 [USACO15JAN]草鉴定Grass Cownoisseur的更多相关文章

  1. [Luogu P3119] [USACO15JAN]草鉴定Grass Cownoisseur (缩点+图上DP)

    题面 传送门:https://www.luogu.org/problemnew/show/P3119 Solution 这题显然要先把缩点做了. 然后我们就可以考虑如何处理走反向边的问题. 像我这样的 ...

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

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

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

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

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

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

  5. P3119 [USACO15JAN]草鉴定Grass Cownoisseur

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

  6. 洛谷—— P3119 [USACO15JAN]草鉴定Grass Cownoisseur || BZOJ——T 3887: [Usaco2015 Jan]Grass Cownoisseur

    http://www.lydsy.com/JudgeOnline/problem.php?id=3887|| https://www.luogu.org/problem/show?pid=3119 D ...

  7. P3119 [USACO15JAN]草鉴定Grass Cownoisseur 分层图或者跑两次最长路

    https://www.luogu.org/problemnew/show/P3119 题意 有一个有向图,允许最多走一次逆向的路,问从1再走回1,最多能经过几个点. 思路 (一)首先先缩点.自己在缩 ...

  8. Luogu 3119 [USACO15JAN]草鉴定Grass Cownoisseur

    思路很乱,写个博客理一理. 缩点 + dp. 首先发现把一个环上的边反向是意义不大的,这样子不但不好算,而且相当于浪费了一次反向的机会.反正一个强连通分量里的点绕一遍都可以走到,所以我们缩点之后把一个 ...

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

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

随机推荐

  1. ubuntu中卸载没有安装完全的软件包

    sudo apt-get autoclean sudo apt-get clean sudo apt-get autoremove

  2. Java Web系统常用的第三方接口

    1.    Web Service 接口 1.1 接口方式说明和优点 在笔者的开发生涯中,当作为接口提供商给第三方提供接口时,以及作为客户端去调用第三方提供的接口时,大部分时候都是使用 Web  Se ...

  3. Python爬取全站妹子图片,差点硬盘走火了!

    在这严寒的冬日,为了点燃我们的热情,今天小编可是给大家带来了偷偷收藏了很久的好东西.大家要注意点哈,我第一次使用的时候,大意导致差点坏了大事哈! 1.所需库安装 2.网站分析 首先打开妹子图的官网(m ...

  4. 如何把list当成栈或者队列来用

    在python里,list和在C.java里的数组差不多,但是python里的list是可变长的,而且python语言也支持倒叙读取,如list[-1]可以读取最后一个元素.但这还不是最厉害的,lis ...

  5. Codeforces Round #505 D. Recovering BST(区间DP)

    首先膜一发网上的题解.大佬们tql. 给你n个单调递增的数字,问是否能够把这些数字重新构成一棵二叉搜索树(BST),且所有的父亲结点和叶子结点之间的gcd > 1? 这个题场上是想暴力试试的.结 ...

  6. debian使用sudo

    debian默认没有sudo ,在命令前无法使用sudo #切换到根用户$ su 输入根用户密码 # apt-get install sudo # nano /etc/sudoers 文件的 User ...

  7. 02-python进阶-文件操作

    新建一个文件 内容是从 0-9的整数 #coding:utf-8 f = open('1.txt','w') #r 只读 w 可写 a追加 for i in range(0,10): f.write( ...

  8. python学习-- {% csrf_token %}

    1.不推荐禁用掉django中的CSRF. 2.我们可以再html页面的form表单中添加csrf_token,带着表单的请求一起发送到服务器去验证. <form  enctype=" ...

  9. 【POJ 2585】Window Pains 拓扑排序

    Description . . . and so on . . . Unfortunately, Boudreaux's computer is very unreliable and crashes ...

  10. Eclipse调试程序及项目的导入导出

    Eclipse调试程序 调试概述: ①   调试就是测试程序的方法,主要的目的就是解决程序的逻辑问题,流程是:发现问题.修改问题.正确执行; ②   以前我们可以使用System.out.printl ...