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

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

考虑一个强连通分量内的点可以随便走,于是缩个点。
然后设f[i]表示1到i最多能走几个点,g[i]表示i到n最多能走几个点,由于没有环的存在,
我们枚举边,用f[u]+g[v]更新答案,最后答案需要减掉1所在scc的大小。
 
代码:
#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的更多相关文章

  1. BZOJ 3887/Luogu P3119: [Usaco2015 Jan]Grass Cownoisseur (强连通分量+最长路)

    分层建图,反向边建在两层之间,两层内部分别建正向边,tarjan缩点后,拓扑排序求一次1所在强连通分量和1+n所在强联通分量的最长路(长度定义为路径上的强联通分量内部点数和).然后由于1所在强连通分量 ...

  2. BZOJ_2208_[Jsoi2010]连通数_强连通分量+拓扑排序+手写bitset

    BZOJ_2208_[Jsoi2010]连通数_强连通分量+拓扑排序+手写bitset Description Input 输入数据第一行是图顶点的数量,一个正整数N. 接下来N行,每行N个字符.第i ...

  3. BZOJ3887 [Usaco2015 Jan] Grass Cownoisseur 【tarjan】【DP】*

    BZOJ3887 [Usaco2015 Jan] Grass Cownoisseur Description In an effort to better manage the grazing pat ...

  4. poj 2762(强连通分量+拓扑排序)

    题目链接:http://poj.org/problem?id=2762 题意:给出一个有向图,判断任意的两个顶点(u,v)能否从u到达v,或v到达u,即单连通,输出Yes或No. 分析:对于同一个强连 ...

  5. BZOJ1924:[SDOI2010]所驼门王的宝藏(强连通分量,拓扑排序)

    Description Input 第一行给出三个正整数 N, R, C. 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室 ...

  6. 2019ICPC(银川) - Delivery Route(强连通分量 + 拓扑排序 + dijkstra)

    Delivery Route 题目:有n个派送点,x条双向边,y条单向边,出发点是s,双向边的权值均为正,单向边的权值可以为负数,对于单向边给出了一个限制:如果u->v成立,则v->u一定 ...

  7. CDOJ 图论专题 A.不是图论 强连通分量+拓扑排序 经典

    题目链接  在其中纠错第一次wa代码 #include <cstdio> #include <cstring> #include <cstdlib> #includ ...

  8. POJ 2762 Going from u to v or from v to u?(强连通分量+拓扑排序)

    职务地址:id=2762">POJ 2762 先缩小点.进而推断网络拓扑结构是否每个号码1(排序我是想不出来这点的. .. ).由于假如有一层为2的话,那么从此之后这两个岔路的点就不可 ...

  9. [bzoj3887][Usaco2015 Jan]Grass Cownoisseur_trajan_拓扑排序_拓扑序dp

    [Usaco2015 Jan]Grass Cownoisseur 题目大意:给一个有向图,然后选一条路径起点终点都为1的路径出来,有一次机会可以沿某条边逆方向走,问最多有多少个点可以被经过?(一个点在 ...

随机推荐

  1. 浅谈拒绝服务攻击的原理与防御(4):新型DDOS攻击 – Websocket和临时透镜

    0×01 前言 前几天我已经分别发了三篇关于DDOS攻击相关的文章,我也是第一次在freebuf上发表这种文章,没想到有那么多人点击我真的很开心,前几天我为大家介绍的DDOS攻击的方法和原理都是已经出 ...

  2. Android 存储(本地存储 SD卡存储 SharedPreference SQLite ContentProvider)

    本文出自:http://blog.csdn.net/dt235201314/article/details/73176149 源码下载欢迎Star(updating):https://github.c ...

  3. Linux Distribution

    来自为知笔记(Wiz)

  4. python入门之搭建环境

    进入以下网站:python.org 选择你喜欢(需要)的版本下载 点击下载即可,本次提供下载:python3.6.3 (国外架设,非常慢) ,用百度的平台吧:python3.6.1,多谢百度. 开始安 ...

  5. vue2.0 + vux (四)Home页

    1.综合页(首页) Home.vue <!-- 首页 --> <template> <div> <!-- 顶部 标题栏 --> <app-head ...

  6. android:使用gallery和imageSwitch制作可左右循环滑动的图片浏览器

    为了使图片浏览器左右无限循环滑动 我们要自己定义gallery的adapter 假设要想自己定义adapter首先要了解这几个方法 @Override public int getCount() { ...

  7. mycat 连续分片 -&gt; 按日期(天)分片

    1,按日期(天)分片 按日期(天)分片:从開始日期算起,依照天数来分片 比如,从2016-01-01.每10天一个分片 注意事项:须要提前将分片规划好,建好.否则有可能日期超出实际配置分片数 2,加入 ...

  8. 显示和隐藏Mac隐藏文件的命令

    显示Mac隐藏文件的命令:defaults write com.apple.finder AppleShowAllFiles -bool true 隐藏Mac隐藏文件的命令:defaults writ ...

  9. Java EJB JBoss

    JBoss:JBoss是web服务器的一种,主要做EJB容器,和tomcat集成就可以jsp,servlet,ejb通吃了JBoss有两种版本,一种是独立的,一种是和tomcat集成的,当然都是免费的 ...

  10. Vue 资源

    一. 资源教程 综合类 vuejs 英文资料 Vue中文资料总汇 Vue.js 的一些资源索引 vue资料 入门类 vue 快速入门 Vue.js 中文系列视频教程 on Laravist 英文教程 ...