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

贝西总是从1号草场出发,最后回到1号草场。她想经过尽可能多的草场,贝西在通一个草场只吃一次草,所以一个草场可以经过多次。

因为草场是单行道连接,这给贝西的品鉴工作带来了很大的不便,贝西想偷偷逆向行走一次,但最多只能有一次逆行。问,贝西最多能吃到多少个草场的牧草。

输入:

第一行:草场数n,道路数m。

以下m行,每行x和y表明有x到y的单向边,不会有重复的道路出现。

输出:

一个数,逆行一次最多可以走几个草场。

输入 #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 
好久没有这么正式的将题面搬过来了;
显然需要tarjan求强连通分量;
但是我只会到这里,但是看题;
允许一条边反向,有点眼熟,啊,那个,就是那个
我们先缩点,dijkstra正向求最长路,再反向求最长路
枚举反向的边;
dis1[x]+dis2[v]-sum[belong[1]];
但是我们要保证能回去
#include<cstdio>
#include<cstring>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
const int maxn=1e5+;
int n,m,pre[maxn],last[maxn],other[maxn],l;
int pre0[maxn],last0[maxn],other0[maxn],l0;
void add0(int x,int y)
{
l0++;
pre0[l0]=last0[x];
last0[x]=l0;
other0[l0]=y;
}
int dfn[maxn],low[maxn],cnt;
void add(int x,int y)
{
l++;
pre[l]=last[x];
last[x]=l;
other[l]=y;
}
int pre2[maxn],last2[maxn],other2[maxn],l2;
void add2(int x,int y)
{
l2++;
pre2[l2]=last2[x];
last2[x]=l2;
other2[l2]=y;
} stack<int> s;
int belong[maxn],qw; void dfs(int x)
{
dfn[x]=low[x]=++cnt;
s.push(x);
for(int p=last[x];p;p=pre[p])
{
int v=other[p];
if(!dfn[v])
{
dfs(v);
low[x]=min(low[x],low[v]);
}
else if(!belong[v])
{
low[x]=min(low[x],dfn[v]);
}
}
if(dfn[x]==low[x])
{
belong[x]=++qw;
//printf("%d ",qw);
while()
{
int y=s.top();
s.pop();
belong[y]=qw;
if(x==y) break;
}
}
} int sum[maxn];
int ans;
int vis[maxn];
int dis1[maxn],dis2[maxn];
priority_queue<pair<int,int> >q;
void dijkstra(int x)
{
memset(vis,,sizeof(vis));
dis1[x]=sum[x];
q.push(make_pair(dis1[x],x));
while(!q.empty())
{
int u=q.top().second;
q.pop();
// printf("%d\n!",u);
// printf("%d\n?",last[u]);
// if(vis[u]) continue;
// vis[u]=1;
for(int p=last0[u];p;p=pre0[p])
{
int v=other0[p];
//printf("!!");
if(dis1[v]<dis1[u]+sum[v])
{
dis1[v]=dis1[u]+sum[v];
q.push(make_pair(dis1[v],v));
//printf("%d\n",dis1[v]);
}
}
}
} void dijkstra2(int x)
{
memset(vis,,sizeof(vis));
dis2[x]=sum[x];
q.push(make_pair(dis2[x],x));
while(!q.empty())
{
int u=q.top().second;
q.pop();
// if(vis[u]) continue;
// vis[u]=1;
for(int p=last2[u];p;p=pre2[p])
{
int v=other2[p];
if(dis2[v]<dis2[u]+sum[v])
{
dis2[v]=dis2[u]+sum[v];
q.push(make_pair(dis2[v],v));
}
}
}
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
}
for(int i=;i<=n;i++)
{
if(!dfn[i]) dfs(i);
} //memset(pre,0,sizeof(pre)); for(int i=;i<=n;i++)
{
sum[belong[i]]++;
}
//for(int i=1;i<=qw;i++) printf("%d ",sum[i]);
for(int i=;i<=n;i++)
{
for(int p=last[i];p;p=pre[p])
{
int v=other[p];
if(belong[i]!=belong[v])
{
add0(belong[i],belong[v]);
add2(belong[v],belong[i]);
}
}
}
ans=sum[belong[]];
dijkstra(belong[]);
dijkstra2(belong[]);
//for(int i =1;i<=n;i++) printf("%d ",dis1[i]);
memset(vis,,sizeof(vis));
for(int i=;i<=n;i++)
{
if(vis[belong[i]]||!dis1[belong[i]]) continue;
vis[belong[i]]=;
int x=belong[i];
for(int p=last2[x];p;p=pre2[p])
{
int v=other2[p];
if(!dis2[v]) continue;
ans=max(ans,dis1[x]+dis2[v]-sum[belong[]]);
}
}
printf("%d",ans);
return ;
}

												

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

  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

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

  5. 洛谷P3119 USACO15JAN 草鉴定

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

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

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

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

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

  8. P3119 [USACO15JAN]草鉴定[SCC缩点+SPFA]

    题目描述 约翰有n块草场,编号1到n,这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可能多的草场去品尝牧草. 贝西总是从1号草场出发,最后回到1号草场.她想经过尽可能多的草场,贝西 ...

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

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

随机推荐

  1. 在论坛中出现的比较难的sql问题:29(row_number函数 组内某列的值连续出现3次标记出来)

    原文:在论坛中出现的比较难的sql问题:29(row_number函数 组内某列的值连续出现3次标记出来) 在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘 ...

  2. python之闭包、装饰器

    一.学习Python的时候发现函数内部,还可以写函数,并且可以返回函数.觉得挺新奇的,主要是在探索装饰器(有点像Java的注解)的时候,发现这个理解还是很主要的,所以这里记录一下. 二.闭包 1)首先 ...

  3. processon使用教程

    原文地址:https://www.cnblogs.com/yangliheng/p/6082250.html 一.引言 作为一名IT从业者,不仅要有扎实的知识储备,出色的业务能力,还需要具备一定的软实 ...

  4. kvm第四章-- 虚拟化网络管理

  5. 【转】JRE和JDK的区别

    用一幅图来宏观的看一下 从图中可以看出JDK包含JRE包含JVM. JDK:java development kit (java开发工具) JRE:java runtime environment ( ...

  6. 1+x证书学习日志——css 基本选择符

    ##css选择符                 1:类型选择符 直接用标签名称当作选择符                     特点:选中所有同类元素                 2:id名称 ...

  7. Android笔记(二十六) Android中的广播——BroadcastReceiver

    为了方便进行系统级别的消息通知,Android有一套类似广播的消息机制,每个应用程序都可以对自己感兴趣的广播进行注册,这样该程序就只会接收自己所关心的广播内容,这些广播可能是来自于系统,也可能是来自于 ...

  8. c# 使用序列化

  9. 快上车,react 入门拾遗

    最近朋友圈和微博都刷了一波杰伦的回忆杀–说好不哭,想想都9012了,在学习react如火如荼的路上,也不妨停下脚步来总结总结,朝花夕拾一下. 为了便于阐述,我们还是来段小明和禅师的故事吧. 小明在学习 ...

  10. 小程序数据绑定和setData

    我们wxml没有直接调用数据的能力,我们的逻辑是通过js调用数据,再由js传递给wxml才能够显示出来.那么怎么由js传递给wxml?   首先我的js里面有这样一段代码 process: funct ...