这个题调了一天。。

传送门

读完题目之后我们不难想出这个题是个tarjan缩点问题,因为尽量多的经过草场,所以一号点所在的强连通分量里左右的点都是不需要在进行走逆向边,所能到达的。

然后问题就落在怎么处理我们走这一次逆向边上。

仔细看题目要求,题目要求我们必须从一号点出发,最后回到一号点。所以我想到了建一个逆向的图,虚拟出cnt + 1 , cnt+2,cnt+3.....n+cnt号点,建一个逆向图(用进行缩点之后的点集重新构造),因为我们求出进过草场最多是多少,所以我们将强连通分量中有多少个点在缩点中记录下来(num[i]:表示第ii个强连通分量中有多少个点),将它作为边权。

最后我们只要从1号点所在的强连通分量开始,跑一边最长路就好了,最后输出从1号点到我们虚拟出来的1 + cnt号点就好了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 2e5 + ; inline int read(){
char ch = getchar();
int f = , x = ;
while(ch > '' || ch < ''){if(ch == '-')f = -;ch = getchar();}
while(ch >= '' && ch <= ''){x = (x << ) + (x << ) + ch - '';ch = getchar();}
return x * f;
} int n,m,x,y;
int head[maxn],tot,head2[maxn],tot2;
int ans; struct Edge{
int from,to,next;
}edge[maxn << ],edge2[maxn << ]; void add(int u,int v){
edge[++tot].from = u;
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot;
} void add_edge(int u,int v){
edge2[++tot2].from = u;
edge2[tot2].to = v;
edge2[tot2].next = head2[u];
head2[u] = tot2;
} int dfn[maxn],low[maxn],ind;
int belong[maxn],num[maxn],cnt,stack[maxn],top;
bool ins[maxn]; void tarjan(int x){
low[x] = dfn[x] = ++ind;
ins[x] = true;
stack[++top] = x;
for(int i=head[x];i;i=edge[i].next){
int v = edge[i].to;
if(ins[v]) low[x] = min(low[x] , dfn[v]);
if(!dfn[v]) {
tarjan(v);
low[x] = min(low[x] , low[v]);
}
}
int k = ;
if(dfn[x] == low[x]){
cnt++;
do{
k = stack[top];
num[cnt]++;
top--;
ins[k] = false;
belong[k] = cnt;
} while(k != x);
}
} int dis[maxn];
bool vis[maxn]; void spfa(int s){
queue<int> q;
q.push(s);
dis[s] = ;
vis[s] = true;
while(!q.empty()){
int cur = q.front();
q.pop(); vis[cur] = false;
for(int i=head2[cur];i;i=edge2[i].next){
int v = edge2[i].to;
if(dis[v] < dis[cur] + num[cur]){
dis[v] = dis[cur] + num[cur];
if(vis[v] == ){
q.push(v);
vis[v] = true;
}
}
}
}
} int main(){
n = read(); m = read();
for(int i=;i<=m;i++){
x = read(); y =read();
add(x , y);
}
for(int i=;i<=n;i++)
if(!dfn[i]) tarjan(i);
for(int i=;i<=n;i++)
num[i + cnt] = num[i];
for(int i=;i<=m;i++)
if(belong[edge[i].from] != belong[edge[i].to]){
add_edge(belong[edge[i].from] , belong[edge[i].to]);
add_edge(belong[edge[i].to] , belong[edge[i].from] + cnt);
add_edge(belong[edge[i].from] + cnt , belong[edge[i].to] + cnt);
}
spfa(belong[]);
printf("%d\n",dis[belong[] + cnt]);
return ;
}

洛谷P3119 草鉴定的更多相关文章

  1. 洛谷P3119草鉴定

    题目 草鉴定,tarjan可以用来缩点,优化spfa的时间, 缩点之后就是一个\(DAG\)了,因此完全可以用来跑spfa上的最长路,然后枚举每条边,查看是否这条边的两个节点分别可以到达起点所在的强连 ...

  2. 洛谷3119 草鉴定(tarjan)

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

  3. 【题解】洛谷P3119 Grass Cownoisseur G

    题面:洛谷P3119 Grass Cownoisseur G 本人最近在熟悉Tarjan的题,刷了几道蓝题后,我飘了 趾高气扬地点开这道紫题,我一瞅: 哎呦!这不是分层图吗? 突然就更飘了~~~ 用时 ...

  4. 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur 解题报告

    P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 约翰有\(n\)块草场,编号1到\(n\),这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可 ...

  5. 洛谷——P3119 [USACO15JAN]草鉴定Grass Cownoisseur

    P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 In an effort to better manage the grazing patterns of hi ...

  6. 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur (SCC缩点,SPFA最长路,枚举反边)

    P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 In an effort to better manage the grazing patterns of hi ...

  7. 【洛谷P3119】[USACO15JAN]草鉴定Grass Cownoisseur

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

  8. 洛谷P3119 USACO15JAN 草鉴定

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

  9. 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur

    屠龙宝刀点击就送 Tarjan缩点+拓扑排序 以后缩点后建图看n范围用vector ,或者直接用map+vector 结构体里数据要清空 代码: #include <cstring> #i ...

随机推荐

  1. day7-python基础

  2. faster rcnn算法及源码及论文解析相关博客

    1. 通过代码理解faster-RCNN中的RPN http://blog.csdn.net/happyflyy/article/details/54917514 2. faster rcnn详解 R ...

  3. Betsy Ross Problem

    Matlab学习中的betsy ross 问题.用matlab函数画1777年的美国国旗. 五角星绘制部分是自己想出来的方法去画上的.具体代码参考如下. 先是绘制矩形的函数 function Draw ...

  4. 【Asp.net入门03】第一个ASP.NET 应用程序-创建ASP.NET项目

    本部分主要内容: 创建并运行Asp.net项目 web窗体 数据模型 调用代码隐藏方法 数据验证 1.操作步骤 第一步:启动Visual Studio 2013,然后从File(文件)菜单中选择New ...

  5. PyQt 5.4参考指南 ---- PyQt5和PyQt4之间的差异

    欢迎关注博主主页,学习python视频资源,还有大量免费python经典文章 sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频) https://study.163.com/course/in ...

  6. noi题库(noi.openjudge.cn) 1.13编程基础之综合应用 T12 分数求和

    12:分数求和 描述 输入n个分数并对他们求和,并用最简形式表示.所谓最简形式是指:分子分母的最大公约数为1:若最终结果的分母为1,则直接用整数表示. 如:5/6.10/3均是最简形式,而3/6需要化 ...

  7. SQL语句(十七)综合练习_分组查询_内嵌查询_视图使用

    Select * from Student Select * From Course Select * from SC --子查询 低于总平均成绩的女同学成绩 Select Grade from St ...

  8. 蓝桥杯 剪邮票 DFS (不错的题目)

    剪邮票 如[图1.jpg], 有12张连在一起的12生肖的邮票.现在你要从中剪下5张来,要求必须是连着的.(仅仅连接一个角不算相连)比如,[图2.jpg],[图3.jpg]中,粉红色所示部分就是合格的 ...

  9. [洛谷P4492] [HAOI2018]苹果树

    洛谷题目链接:[HAOI2018]苹果树 题目背景 HAOI2018 Round2 第一题 题目描述 小 C 在自己家的花园里种了一棵苹果树, 树上每个结点都有恰好两个分支. 经过细心的观察, 小 C ...

  10. js截取字符串substr和substring的区别

    定义substr() 方法可在字符串中抽取从 start 下标开始的指定数目的字符.substring() 方法用于提取字符串中介于两个指定下标之间的字符. 语法substr()        str ...