http://www.lydsy.com/JudgeOnline/problem.php?id=3887||

https://www.luogu.org/problem/show?pid=3119

Description

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.
给一个有向图,然后选一条路径起点终点都为1的路径出来,有一次机会可以沿某条边逆方向走,问最多有多少个点可以被经过?(一个点在路径中无论出现多少正整数次对答案的贡献均为1)

Input

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

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.
 

Sample Input

7 10
1 2
3 1
2 5
2 4
3 7
3 5
3 6
6 5
7 2
4 7

Sample Output

6

HINT

 

Source

Gold&鸣谢18357

先把原图缩点,跑出从1到n和从n到1的最多可以遍历的牧场数,

枚举每个边做无向边的情况更新答案

SPFA跑最多牧场数

 #include <cstdio>
#include <queue>
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b) const int INF(0x3f3f3f3f);
const int N(1e5+);
int n,head[N],sumedge;
struct Edge
{
int v,next;
Edge(int v=,int next=):v(v),next(next){}
}edge[N];
inline void ins(int u,int v)
{
edge[++sumedge]=Edge(v,head[u]);
head[u]=sumedge;
} int tim,dfn[N],low[N];
int top,Stack[N],instack[N];
int sumcol,col[N],point[N];
void DFS(int u)
{
low[u]=dfn[u]=++tim;
Stack[++top]=u; instack[u]=;
for(int v,i=head[u];i;i=edge[i].next)
{
v=edge[i].v;
if(!dfn[v]) DFS(v),low[u]=min(low[u],low[v]);
else if(instack[v]) low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u])
{
col[u]=++sumcol;
point[sumcol]++;
for(;Stack[top]!=u;top--)
{
point[sumcol]++;
col[Stack[top]]=sumcol;
instack[Stack[top]]=;
}
instack[u]=; top--;
}
} int hed[N],had[N],sum;
struct E
{
int v,next,w;
E(int v=,int next=,int w=):v(v),next(next),w(w){}
}e[N][];
inline void insert(int u,int v)
{
e[++sum][]=E(v,hed[u],point[v]);
hed[u]=sum;
e[sum][]=E(u,had[v],point[u]);
had[v]=sum;
} bool inq[N];
int v1[N],v2[N];
void SPFA(int op,int s,int *val,int *head)
{
for(int i=;i<=sumcol;i++)
inq[i]=,val[i]=-INF;
val[s]=point[s];
std::queue<int>que;
que.push(s);
for(int u,v;!que.empty();)
{
u=que.front(); que.pop(); inq[u]=;
for(int i=head[u];i;i=e[i][op].next)
{
v=e[i][op].v;
if(val[v]<val[u]+e[i][op].w)
{
val[v]=val[u]+e[i][op].w;
if(!inq[v]) inq[v]++,que.push(v);
}
}
}
} inline void read(int &x)
{
x=; register char ch=getchar();
for(;ch>''||ch<'';) ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-'';
} int AC()
{
int m; read(n),read(m);
for(int u,v;m--;)
read(u),read(v),ins(u,v);
for(int i=;i<=n;i++)
if(!dfn[i]) DFS(i);
for(int v,u=;u<=n;u++)
for(int i=head[u];i;i=edge[i].next)
{
v=edge[i].v;
if(col[u]!=col[v]) insert(col[u],col[v]);
}
int ans=-INF;
SPFA(,col[],v1,hed);
SPFA(,col[],v2,had);
for(int v,u=;u<=sum;u++)
for(int i=hed[u];i;i=e[i][].next)
{
v=e[i][].v;
ans=max(ans,v1[v]+v2[u]);
}
for(int v,u=;u<=sum;u++)
for(int i=had[u];i;i=e[i][].next)
{
v=e[i][].v;
ans=max(ans,v1[u]+v2[v]);
}
printf("%d\n",ans-point[col[]]);
return ;
} int Hope=AC();
int main(){;}

SPFA AC

Topsort跑最多牧场数

 #include <cstdio>
#include <queue>
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b) const int INF(0x3f3f3f3f);
const int N(1e5+);
int n,head[N],sumedge;
struct Edge
{
int v,next;
Edge(int v=,int next=):v(v),next(next){}
}edge[N];
inline void ins(int u,int v)
{
edge[++sumedge]=Edge(v,head[u]);
head[u]=sumedge;
} int tim,dfn[N],low[N];
int top,Stack[N],instack[N];
int sumcol,col[N],point[N],rd[N],cd[N];
void DFS(int u)
{
low[u]=dfn[u]=++tim;
Stack[++top]=u; instack[u]=;
for(int v,i=head[u];i;i=edge[i].next)
{
v=edge[i].v;
if(!dfn[v]) DFS(v),low[u]=min(low[u],low[v]);
else if(instack[v]) low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u])
{
col[u]=++sumcol;
point[sumcol]++;
for(;Stack[top]!=u;top--)
{
point[sumcol]++;
col[Stack[top]]=sumcol;
instack[Stack[top]]=;
}
instack[u]=; top--;
}
} int hed[N],had[N],sum;
struct E
{
int v,next,w;
E(int v=,int next=,int w=):v(v),next(next),w(w){}
}e[N][];
inline void insert(int u,int v)
{
e[++sum][]=E(v,hed[u],point[v]);
hed[u]=sum;
e[sum][]=E(u,had[v],point[u]);
had[v]=sum;
} int v1[N],v2[N];
#define max(a,b) (a>b?a:b)
void Topsort(int op,int s,int *val,int *head,int *du)
{
std::queue<int>que;
for(int i=;i<=sumcol;i++)
{
if(!du[i]) que.push(i);
val[i]=-INF;
}
val[s]=point[s];
for(int u,v;!que.empty();)
{
u=que.front(); que.pop();
for(int i=head[u];i;i=e[i][op].next)
{
v=e[i][op].v;
val[v]=max(val[v],val[u]+e[i][op].w);
if(--du[v]==) que.push(v);
}
}
} inline void read(int &x)
{
x=; register char ch=getchar();
for(;ch>''||ch<'';) ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-'';
} int AC()
{
int m; read(n),read(m);
for(int u,v;m--;)
read(u),read(v),ins(u,v);
for(int i=;i<=n;i++)
if(!dfn[i]) DFS(i);
for(int v,u=;u<=n;u++)
for(int i=head[u];i;i=edge[i].next)
{
v=edge[i].v;
if(col[u]==col[v]) continue;
rd[col[v]]++,cd[col[u]]++;
insert(col[u],col[v]);
}
int ans=-INF;
Topsort(,col[],v1,hed,rd);
Topsort(,col[],v2,had,cd);
for(int v,u=;u<=sum;u++)
for(int i=hed[u];i;i=e[i][].next)
{
v=e[i][].v;
ans=max(ans,v1[v]+v2[u]);
}
for(int v,u=;u<=sum;u++)
for(int i=had[u];i;i=e[i][].next)
{
v=e[i][].v;
ans=max(ans,v1[u]+v2[v]);
}
printf("%d\n",ans-point[col[]]);
return ;
} int Hope=AC();
int main(){;}

Topsort AC

洛谷—— P3119 [USACO15JAN]草鉴定Grass Cownoisseur || BZOJ——T 3887: [Usaco2015 Jan]Grass Cownoisseur的更多相关文章

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

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

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

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

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

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

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

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

  5. 洛谷P3119 USACO15JAN 草鉴定

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

  6. 洛谷3119 [USACO15JAN]草鉴定Grass Cownoisseur

    原题链接 显然一个强连通分量里所有草场都可以走到,所以先用\(tarjan\)找强连通并缩点. 对于缩点后的\(DAG\),先复制一张新图出来,然后对于原图中的每条边的终点向新图中该边对应的那条边的起 ...

  7. P3119 [USACO15JAN]草鉴定Grass Cownoisseur

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

  8. luogu P3119 [USACO15JAN]草鉴定Grass Cownoisseur

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

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

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

随机推荐

  1. Linux 强行终止

    kill -9 pid pid是进程号 -9 代表的是数字 INT 2 这个就是你在bash下面用Ctrl+C 来结束一个程序时,bash会向进程发送这个信号,默认的,进程收到这个程序会结束. 你可以 ...

  2. 固定管线shader编写:基本属性

    欢迎转载!转载时请注明出处:http://write.blog.csdn.net/postedit/50753008 shader 部分介绍: properties:属性部分 material:材质部 ...

  3. SVGImageView

    In essence, I'm trying to layer multiple ImageViews (one of which is a floor plan, the other a recta ...

  4. dns tunnel 使用 nishang 下载TXT里的cmd(TXT里)实现CC command+ ceye实现数据外发

    摘自:https://hk.saowen.com/a/a06909f1c57cb8452db969b3deede4151de42a7d69f4bb52c5bf027033fb91bd Powershe ...

  5. UVa 11722(几何概率)

    题意:你和你的朋友要乘坐火车,并且都会在A城市相遇,你会在(t1,t2)中的任意时刻以相同的概率密度到达, 你朋友会在(s1,s2)中的任意时刻以相同的概率密度到达,你们的火车在A城市都会停留w分钟, ...

  6. 05.使用jdk发布webservice服务

    无论服务端是用什么写的,使用框架写的还是用jdk写的,它都会发布出来这样一个东西.主要你遵循咱们这七个步骤来走就可以调用了. 咱们现在转换一下角色,自己发布一个服务让别人去调.怎么来发布一个服务? 我 ...

  7. (Go)03.go类型

    1.1 变量Go 是静态类型语⾔言,不能在运⾏行期改变变量类型.使⽤用关键字 var 定义变量,⾃自动初始化为零值.如果提供初始化值,可省略变量类型,由编译器⾃自动推断. var x int var ...

  8. [牛客挑战赛 30D] 小A的昆特牌 解题报告 (组合数学)

    interlinkage: https://ac.nowcoder.com/acm/contest/375/D description: solution: 我们枚举步兵的数量$x$,还剩下$S-x$ ...

  9. python 下 excel,csv 文件的读写

    python 可以用利用xlrd 库读取数据excel数据,可以用xlwt写入excel数据,用csv 操作csv文件 xlrd xlwt  python 模块 官方链接  https://pypi. ...

  10. My first blog for java

    我的第一个java程序: package com.hellojava; /** * @author 沽-名-钓-誉 */ public class HelloJava{ /** * @param 输出 ...