约翰有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. idea 中 下载源码:Sources not download for:

    使用idea 下载源码出现:Sources not found for: 解决方案:在对应的pom.xml 文件中打开 terminal,执行 mvn命令: mvn dependency:source ...

  2. 怎样解决Script error报错问题

    如果脚本网址与网页网址不在同一个域(比如使用了 CDN), 那如果这个脚本执行报错了, 就会报:Script error. 由于同源策略, 浏览器禁止向外部脚本泄漏信息, 因此不会提供完整的报错信息, ...

  3. shell 学习笔记8-case条件语句

    一.case语句简介 1.什么是case条件语句 case条件语句就相当于多分支的if/elif/else条件语句,但是比这样的语句更规范更好看,经常被用在失效系统服务启动脚本等企业应用中 程序将ca ...

  4. U盘安装Ubuntu14.04&配置远程win10远程连接

    1.U盘安装Ubuntu:https://blog.csdn.net/baigoocn/article/details/26561473 2.win10远程访问Ubuntu系统:https://www ...

  5. 用ajax和PHP实现简单的流程管理

    首先要先有一个新建流程的页面xinjian.php <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ...

  6. iPhone电话与短信相关代码小结

    关于iPhone上电话与短信相关功能,做一个简单总结: 使用公开SDK能实现的功能: (1)获取和操作通讯录.使用函数 ABAddressBookRequestAccessWithCompletion ...

  7. 剑指offer-链表相关

    剑指offer面试常考手撸算法题-链表篇 1. 从头到尾打印链表 class Solution { public: // 可以先压栈,再出栈到vector // 时间/空间:O(n) vector&l ...

  8. 采集代理ip 地址【西刺,快代理】

    # 嗯,...因为经常需要使用代理去抓一点东西,就有了下面一段代码,第一版不是很好,后面用到了再来优化 import re,pymysql,time,redis from urllib.request ...

  9. (坑爹错误)记录prometheus中配置alertmanager.yml一次报错

    global: resolve_timeout: 5m #处理超时时间,默认为5min smtp_smarthost: 'smtp.sina.com:25' # 邮箱smtp服务器代理 smtp_fr ...

  10. CI,CD理解

    一.什么是CI,CD ​ 当我们在谈论现代的软件编译和发布流程的时候,经常会听到CI 和CD这样的缩写短语.CI很容易理解,就是持续集成. ​ 但是CD既可以指代码持续交付,也可理解为代码持续部署.C ...