洛谷P3119 草鉴定
这个题调了一天。。
读完题目之后我们不难想出这个题是个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 草鉴定的更多相关文章
- 洛谷P3119草鉴定
题目 草鉴定,tarjan可以用来缩点,优化spfa的时间, 缩点之后就是一个\(DAG\)了,因此完全可以用来跑spfa上的最长路,然后枚举每条边,查看是否这条边的两个节点分别可以到达起点所在的强连 ...
- 洛谷3119 草鉴定(tarjan)
题目大意 约翰有\(n\)块草场,编号\(1\)到\(n\),这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可能多的草场去品尝牧草. 贝西总是从\(1\)号草场出发,最后回到\(1 ...
- 【题解】洛谷P3119 Grass Cownoisseur G
题面:洛谷P3119 Grass Cownoisseur G 本人最近在熟悉Tarjan的题,刷了几道蓝题后,我飘了 趾高气扬地点开这道紫题,我一瞅: 哎呦!这不是分层图吗? 突然就更飘了~~~ 用时 ...
- 洛谷 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
草鉴定Grass Cownoisseur 题目链接 约翰有n块草场,编号1到n,这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可能多的草场去品尝牧草. 贝西总是从1号草场出发,最后 ...
- 洛谷P3119 USACO15JAN 草鉴定
题目描述 In an effort to better manage the grazing patterns of his cows, Farmer John has installed one-w ...
- 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur
屠龙宝刀点击就送 Tarjan缩点+拓扑排序 以后缩点后建图看n范围用vector ,或者直接用map+vector 结构体里数据要清空 代码: #include <cstring> #i ...
随机推荐
- JS的异步
1.异步 程序中现在运行的部分和将来运行的部分之间的关系是异步编程的核心. 多数JavaScript开发者从来没有认真思考过自己程序中的异步到底是如何出现的,以及为什么会出现,也没有探索过处理异步的其 ...
- bzoj 1914: [Usaco2010 OPen]Triangle Counting 数三角形
USACO划水中... 题目中要求经过原点的三角形数目,但这种三角形没什么明显的特点并不好求,所以可以求不经过原点的三角形数量. 对于一个非法三角形,它离原点最近的那条边连接的两个点所连的两条边一定在 ...
- easyUI datetimebox 自定义显示格式
http://blog.csdn.net/littlewolf766/article/details/7329123 项目里需要显示自定义显示格式,比如只显示yyy,yyyy-mm,yyyy-mm-d ...
- shell 变量定义使用
shell 中变量的几种类型: 1.局部变量:只在当前 shell 可用的变量, 2.环境变量:当前 shell 的子进程也可用的变量 3.shell 变量:一些由 shell 设置的特殊变量,如:$ ...
- python 冒泡法 排序
冒泡排序 冒泡排序(Bubble Sort):重复地遍历要排序的数列,依次比较两个元素,如果他们的顺序不符就把他们交换过来.就像气泡一样,需要排序的元素通过比较.交换位置,一点一点浮到对应的位置. 个 ...
- 六、java异常处理
目录 一.异常的概念 二.异常的分类 三.异常的捕获和处理 四.使用自定义异常 一.异常的概念 java异常是指java提供的用于处理程序运行过程中错误的一种机制 所谓错误是指在程序运行的过程中发生的 ...
- CF&&CC百套计划1 Codeforces Round #449 C. Willem, Chtholly and Seniorious (Old Driver Tree)
http://codeforces.com/problemset/problem/896/C 题意: 对于一个随机序列,执行以下操作: 区间赋值 区间加 区间求第k小 区间求k次幂的和 对于随机序列, ...
- 微信 js-sdk
使用方法 http://mp.weixin.qq.com/wiki/11/74ad127cc054f6b80759c40f77ec03db.html Demo http://203.195.235.7 ...
- Dialog插件artDialog
经本人测试,发现没有layer好用,因为artDialog不能拖拽.不过除了拖拽,其他还蛮简洁的,在自定义上的灵活性也还可以.下面是我自己写的测试demo. <!DOCTYPE html> ...
- spring-boot RestTemplate 连接池
以前我们项目都是基于Apache HttpClient 连接池进行web 接口调用,后来用spring-boot, 发现 RestTemplate 挺好用. 简单介绍下: 什么是RestTemplat ...