洛谷—— 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
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
Output
Sample Input
1 2
3 1
2 5
2 4
3 7
3 5
3 6
6 5
7 2
4 7
Sample Output
HINT
Source
先把原图缩点,跑出从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的更多相关文章
- 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur 解题报告
P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 约翰有\(n\)块草场,编号1到\(n\),这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可 ...
- 洛谷——P3119 [USACO15JAN]草鉴定Grass Cownoisseur
P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 In an effort to better manage the grazing patterns of hi ...
- 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur (SCC缩点,SPFA最长路,枚举反边)
P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 In an effort to better manage the grazing patterns of hi ...
- 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur
屠龙宝刀点击就送 Tarjan缩点+拓扑排序 以后缩点后建图看n范围用vector ,或者直接用map+vector 结构体里数据要清空 代码: #include <cstring> #i ...
- 洛谷P3119 USACO15JAN 草鉴定
题目描述 In an effort to better manage the grazing patterns of his cows, Farmer John has installed one-w ...
- 洛谷3119 [USACO15JAN]草鉴定Grass Cownoisseur
原题链接 显然一个强连通分量里所有草场都可以走到,所以先用\(tarjan\)找强连通并缩点. 对于缩点后的\(DAG\),先复制一张新图出来,然后对于原图中的每条边的终点向新图中该边对应的那条边的起 ...
- P3119 [USACO15JAN]草鉴定Grass Cownoisseur
题目描述 In an effort to better manage the grazing patterns of his cows, Farmer John has installed one-w ...
- luogu P3119 [USACO15JAN]草鉴定Grass Cownoisseur
题目描述 In an effort to better manage the grazing patterns of his cows, Farmer John has installed one-w ...
- P3119 [USACO15JAN]草鉴定Grass Cownoisseur 分层图或者跑两次最长路
https://www.luogu.org/problemnew/show/P3119 题意 有一个有向图,允许最多走一次逆向的路,问从1再走回1,最多能经过几个点. 思路 (一)首先先缩点.自己在缩 ...
随机推荐
- 7种炫酷HTML5 SVG液态水滴融合分解动画特效
这是一组使用HTML5 SVG过滤器制作的炫酷液态水滴融合分解动画特效.这些SVG动画特效使一些HTML元素.如菜单.分页button.APP.选择框等元素的过渡动画像几粒水滴一样融合分解.效果很的酷 ...
- 2016.04.19,英语,《Vocabulary Builder》Unit 16
top, comes from topos, the Greek word for 'place'. ectopic: [ek'tɑːpɪk] adj. [医]异位的,异常的 topical: ['t ...
- php如何将网上的图片下载到本地
<?phpheader("Content-Type: application/force-download");header("Content-Dispositio ...
- SwiftUI 官方教程(二)
SwiftUI 官方教程(二) 2. 自定义 Text View 为了自定义 view 的显示,我们可以自己更改代码,或者使用 inspector 来帮助我们编写代码. 在构建 Landmarks 的 ...
- vcpkg错误分析方法
最近在使用vcpkg时,经常会碰到CMake错误. 有些以前能编译通过的包, 过一段时间又不能编译错误了. 错误提示一般是CMake错误, 弄得很郁闷. 我采用以下步骤解决了问题: 分析错误 查看错误 ...
- BZOJ 2002 LCT板子题
思路: LCT啊... (分块也行) 不过YOUSIKI出了一道“弹飞大爷” 就不能用分块水过去了 //By SiriusRen #include <cstdio> #include &l ...
- POJ 3275 Floyd传递闭包
题意:Farmer John想按照奶牛产奶的能力给她们排序.现在已知有N头奶牛(1 ≤ N ≤ 1,000).FJ通过比较,已经知道了M(1 ≤ M ≤ 10,000)对相对关系.每一对关系表示为&q ...
- java三大版本解析
JAVA三大版本代表着JAVA技术的三个应用领域:JAVASE.JAVAME.JAVAEE. JAVA以前很长一段时间被称为JAVA2,所以现在很多人习惯称为J2SE.J2ME.J2EE,它们表示的含 ...
- SQL查询中选取某个字段的前几个字符的方法
在统计某种数据名称是否存在规律时,可以通过group by进行统计,但是有时候存在钱几个字符相同,后面字符不同的情形.这样可以通过按照前几个字符串进行统计,SqlServer和Oracle中都可以使用 ...
- 谷歌vimium配置
谷歌不得不说真的是一个非常好用的浏览器(之前用的浏览器真的好low),推荐一款非常极客的的插件vimium,让你使用彻底告别鼠标,瞬间感觉高大上... 默认配置: j: 向下细微滚动窗口. k:向上 ...