P3119 [USACO15JAN]草鉴定
约翰有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]草鉴定的更多相关文章
- 洛谷 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
题目描述 In an effort to better manage the grazing patterns of his cows, Farmer John has installed one-w ...
- 洛谷P3119 USACO15JAN 草鉴定
题目描述 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,最多能经过几个点. 思路 (一)首先先缩点.自己在缩 ...
- P3119 [USACO15JAN]草鉴定[SCC缩点+SPFA]
题目描述 约翰有n块草场,编号1到n,这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可能多的草场去品尝牧草. 贝西总是从1号草场出发,最后回到1号草场.她想经过尽可能多的草场,贝西 ...
- [Luogu P3119] [USACO15JAN]草鉴定Grass Cownoisseur (缩点+图上DP)
题面 传送门:https://www.luogu.org/problemnew/show/P3119 Solution 这题显然要先把缩点做了. 然后我们就可以考虑如何处理走反向边的问题. 像我这样的 ...
随机推荐
- hdu 1501 贪心问题
这道题目的关键就是逐个搜索的过程 找个时间得复习一下dfs了 这里使用temp作为参照变量 每次比较以后(由于已经排序好) 已temp为参照进行下一次的比较
- 火狐浏览器 访问所有HTTPS网站显示连接不安全解决办法
当 Firefox 连接到一个安全的网站时(网址最开始为“https://”),它必须确认该网站出具的证书有效且使用足够高的加密强度.如果证书无法通过验证,或加密强度过低,Firefox 会中止连接到 ...
- opencv Cascade Classifier Training中 opencv_annotation命令
在win7 cmd中试了官方的指令opencv_annotation --annotations=/path/to/annotations/file.txt --images=/path/to/ima ...
- 【转载】 Asp.Net MVC网站提交富文本HTML标签内容抛出异常
今天开发一个ASP.NET MVC网站时,有个页面使用到了FCKEditor富文本编辑器,通过Post方式提交内容时候抛出异常,仔细分析后得出应该是服务器阻止了带有HTML标签内容的提交操作,ASP. ...
- vue使用技巧:Promise + async + await 解决组件间串行编程问题
业务场景描述 大家都通过互联网投递过简历,比如在智联.58.猎聘等平台.投递心仪的职位前一般都需要前提创建一份简历,简历编辑界面常规的布局最上面是用户的个人基本信息,如姓名.性别.年龄.名族等,接着是 ...
- JS如何做2048(详细)
在做2048之前,我们首先要了解它的游戏规则,以及运行逻辑 首先,来看上半部分 除了标题外还有记录每次获得的分数,以及总分数,还有一个重新开始按钮,这个最大分数会保存下来. 来看页面内容 页面内容由1 ...
- ssh免密登陆(简单快捷)
介绍免密登陆配合下边这张图可以了解下过程: 假设现在A要通过免密登陆B 在A上的操作: 1.终端输入ssh-keygen (后边可以指定加密算法:-t 算法,如果不指定就是默认的rsa) 原理: 首先 ...
- IntelliJ IDEA.2017.3.4(win7 64位)的安装使用
下载 1.Idea与Webstorm同为JetBrains公司的产品,因此安装使用方式也极为相似,首先我们打开IDEA的官方下载网站:https://www.jetbrains.com/idea/,点 ...
- An incompatible version [1.2.10] of the APR based Apache Tomcat Native library is installed, while Tomcat requires version [1.2.14]
这个链接的博主写的很详细,直接推荐:https://blog.csdn.net/zhoukikoo/article/details/80532483
- 【SpringMVC】拦截器
一.概述 1.1 拦截器的异常场合 1.2 拦截器中的方法 二.示例 2.1 定义两个拦截器 2.2 配置拦截器 2.3 执行顺序 三.拦截器应用 3.1 需求 3.2 用户登陆及退出功能开发 3.3 ...