BZOJ_3887_[Usaco2015 Jan]Grass Cownoisseur_强连通分量+拓扑排序+DP
BZOJ_3887_[Usaco2015 Jan]Grass Cownoisseur_强连通分量+拓扑排序+DP
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
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 100500
int head[N],to[N],nxt[N],cnt,siz[N],bel[N],tot,dfn[N],low[N],scc,S[N],ins[N],n,m,xx[N],yy[N],Q[N],in[N],l,r;
int f[N],g[N],ans;
inline void add(int u,int v) {
to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt;
}
void dfs(int x) {
int i; dfn[x]=low[x]=++tot; ins[x]=1; S[++S[0]]=x;
for(i=head[x];i;i=nxt[i]) {
if(!dfn[to[i]]) {
dfs(to[i]);
low[x]=min(low[x],low[to[i]]);
}else if(ins[to[i]]) {
low[x]=min(low[x],dfn[to[i]]);
}
}
if(dfn[x]==low[x]) {
int t=S[S[0]--];
scc++; siz[scc]++; bel[t]=scc; ins[t]=0;
while(x!=t) {
t=S[S[0]--]; siz[scc]++; bel[t]=scc; ins[t]=0;
}
}
}
int main() {
// freopen("wander.in","r",stdin);
// freopen("wander.out","w",stdout);
scanf("%d%d",&n,&m);
if(n==1) {
puts("1"); return 0;
}
int i,x,y;
for(i=1;i<=m;i++) {
scanf("%d%d",&x,&y); add(x,y); xx[i]=x; yy[i]=y;
}
for(i=1;i<=n;i++) if(!dfn[i]) dfs(i);
memset(head,0,sizeof(head)); cnt=0; tot=0;
for(i=1;i<=m;i++) {
x=bel[xx[i]]; y=bel[yy[i]];
if(x!=y) add(x,y),in[y]++,xx[++tot]=x,yy[tot]=y;
}
for(i=1;i<=scc;i++) f[i]=g[i]=-1000000;
int S=bel[1];f[S]=0; g[S]=0;
for(i=1;i<=scc;i++) if(!in[i]) Q[r++]=i;
while(l<r) {
x=Q[l++]; f[x]+=siz[x];
for(i=head[x];i;i=nxt[i]) {
f[to[i]]=max(f[to[i]],f[x]);
if((--in[to[i]])==0) Q[r++]=to[i];
}
}
memset(head,0,sizeof(head)); cnt=0; memset(in,0,sizeof(in));
for(i=1;i<=tot;i++) {
add(yy[i],xx[i]); in[xx[i]]++;
}
l=r=0;
for(i=1;i<=scc;i++) if(!in[i]) Q[r++]=i;
while(l<r) {
x=Q[l++]; g[x]+=siz[x];
for(i=head[x];i;i=nxt[i]) {
g[to[i]]=max(g[to[i]],g[x]);
if((--in[to[i]])==0) Q[r++]=to[i];
}
}
for(i=1;i<=tot;i++) {
ans=max(ans,max(f[xx[i]]+g[yy[i]],f[yy[i]]+g[xx[i]]));
}
printf("%d\n",ans-siz[S]);
}
/*
7 10
1 2
3 1
2 5
2 4
3 7
3 5
3 6
6 5
7 2
4 7
*/ /*
5 8
3 2
4 3
3 5
4 1
2 3
1 3
4 2
1 4
*/
BZOJ_3887_[Usaco2015 Jan]Grass Cownoisseur_强连通分量+拓扑排序+DP的更多相关文章
- BZOJ 3887/Luogu P3119: [Usaco2015 Jan]Grass Cownoisseur (强连通分量+最长路)
分层建图,反向边建在两层之间,两层内部分别建正向边,tarjan缩点后,拓扑排序求一次1所在强连通分量和1+n所在强联通分量的最长路(长度定义为路径上的强联通分量内部点数和).然后由于1所在强连通分量 ...
- BZOJ_2208_[Jsoi2010]连通数_强连通分量+拓扑排序+手写bitset
BZOJ_2208_[Jsoi2010]连通数_强连通分量+拓扑排序+手写bitset Description Input 输入数据第一行是图顶点的数量,一个正整数N. 接下来N行,每行N个字符.第i ...
- BZOJ3887 [Usaco2015 Jan] Grass Cownoisseur 【tarjan】【DP】*
BZOJ3887 [Usaco2015 Jan] Grass Cownoisseur Description In an effort to better manage the grazing pat ...
- poj 2762(强连通分量+拓扑排序)
题目链接:http://poj.org/problem?id=2762 题意:给出一个有向图,判断任意的两个顶点(u,v)能否从u到达v,或v到达u,即单连通,输出Yes或No. 分析:对于同一个强连 ...
- BZOJ1924:[SDOI2010]所驼门王的宝藏(强连通分量,拓扑排序)
Description Input 第一行给出三个正整数 N, R, C. 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室 ...
- 2019ICPC(银川) - Delivery Route(强连通分量 + 拓扑排序 + dijkstra)
Delivery Route 题目:有n个派送点,x条双向边,y条单向边,出发点是s,双向边的权值均为正,单向边的权值可以为负数,对于单向边给出了一个限制:如果u->v成立,则v->u一定 ...
- CDOJ 图论专题 A.不是图论 强连通分量+拓扑排序 经典
题目链接 在其中纠错第一次wa代码 #include <cstdio> #include <cstring> #include <cstdlib> #includ ...
- POJ 2762 Going from u to v or from v to u?(强连通分量+拓扑排序)
职务地址:id=2762">POJ 2762 先缩小点.进而推断网络拓扑结构是否每个号码1(排序我是想不出来这点的. .. ).由于假如有一层为2的话,那么从此之后这两个岔路的点就不可 ...
- [bzoj3887][Usaco2015 Jan]Grass Cownoisseur_trajan_拓扑排序_拓扑序dp
[Usaco2015 Jan]Grass Cownoisseur 题目大意:给一个有向图,然后选一条路径起点终点都为1的路径出来,有一次机会可以沿某条边逆方向走,问最多有多少个点可以被经过?(一个点在 ...
随机推荐
- lstm公式推导
http://blog.csdn.net/u010754290/article/details/47167979 导言 在Alex Graves的这篇论文<Supervised Sequence ...
- Qt中QVector与QList的应用
首先來看看QVector 的基本使用方式,建立一個可容納兩個元素的QVector ,並使用索引方式存取元素值:QVector<double> vect(2); vect[0] = 1.0; ...
- 百科知识 华为手机P7如何更换电池
参考下面 教程 https://item.jd.com/3265516.html
- Mina、Netty、Twisted一起学(七):公布/订阅(Publish/Subscribe)
消息传递有非常多种方式.请求/响应(Request/Reply)是最经常使用的.在前面的博文的样例中.非常多都是採用请求/响应的方式.当server接收到消息后,会马上write回写一条消息到clie ...
- logstash+es+kibana+redis搭建
环境信息: CentOS 6.5 redis 3.0.4 logstash elasticsearch kibana 服务端ip:192.168.0.65 客户端ip:192.168.0.66 关系结 ...
- mysql drop table命令使用总结
drop性能 drop table(innodb引擎) 数量2000w,只需要5m
- MySQL 压缩解决方案
From:https://www.qcloud.com/community/article/876100 导语 描述 MySQL 压缩的使用场景和解决方案,包括压缩传输协议.压缩列解决方案和压缩表解决 ...
- http协议的Last-Modified
$modified_time = $_SERVER['HTTP_IF_MODIFIED_SINCE']; if (strtotime($modified_time) + 3600 > time( ...
- php empty、isset、is_null区别
有关 PHP 的 empty(),isset() 还有 is_null() 这三个函数的用法讨论得已经很多了,而且很多资料也未必能说得很清楚.这里再重复一次,但不是从概念去说,直接用程序例子来说话,应 ...
- httpurlconnection模拟post提交form表单(普通文本和上传文件) (
http://blog.sina.com.cn/s/blog_8417657f0101gvpc.html 用HttpUrlConnection模拟post表单进行文件上传平时很少使用,比较麻烦. 原理 ...