Tarjan水题系列(1):草鉴定Grass Cownoisseur [USACO15JAN]or[luogu P3119]
题目如下:
约翰有n块草场,编号1到n,这些草场由若干条单行道相连。奶牛贝西是美味牧草的鉴赏家,她想到达尽可能多的草场去品尝牧草。
贝西总是从1号草场出发,最后回到1号草场。她想经过尽可能多的草场,贝西在通一个草场只吃一次草,所以一个草场可以经过多次。因为草场是单行道连接,这给贝西的品鉴工作带来了很大的不便,贝西想偷偷逆向行走一次,但最多只能有一次逆行。问,贝西最多能吃到多少个草场的牧草。
大意:
求一个有向图在走一次反向边或不走的情况下走的节点数最多的回到起点的路径的节点数
思路:
首先边可以重复走 所以缩点不会影响答案
缩点后得到的是一个DAG 我们有走一次反向边的机会 此时就相当于在DAG上加一条边 由于要从起点回到起点 这加的一条边的两端要满足一端起点能够到达 一端能通往起点
说到这里算法已经显而易见了 故不赘述了
下面是代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <memory.h>
#define r(x) x=read()
#define MAXX 100005
#define MIN(a,b) (a<b?a:b)
#define MAX(a,b) (a>b?a:b)
using namespace std;
int h[MAXX],h2[MAXX],cnt,dis[][MAXX],flag[MAXX];
int dfn[MAXX],low[MAXX],id[MAXX],w[MAXX],k,top,sta[MAXX],num;
int n,m,ans,ans2,u,to,st;
struct edge{int to,nex;}e[MAXX],yuan[MAXX];
void add(int u,int to)
{
cnt++;
e[cnt]=(edge){to,h[u]},h[u]=cnt;
}
void tarjan(int now)
{
sta[++top]=now;
dfn[now]=low[now]=++k;
for(int i=h[now];i;i=e[i].nex)
{
if(!dfn[e[i].to])
tarjan(e[i].to),low[now]=MIN(low[now],low[e[i].to]);
else
if(!id[e[i].to])
low[now]=MIN(low[now],dfn[e[i].to]);
}
if(low[now]==dfn[now])
{
id[now]=++num;
while(sta[top]!=now){id[sta[top]]=num;top--;}
top--;
}
}
void spfa(int now,int x)
{
queue<int>que;
dis[x][now]=w[now];
que.push(now);
flag[now]=;
while(!que.empty())
{
int p=que.front();que.pop();
for(int i=h[p];i;i=e[i].nex)
{
if(i%!=x) continue;
if(dis[x][e[i].to]<dis[x][p]+w[e[i].to])
{
dis[x][e[i].to]=dis[x][p]+w[e[i].to];
if(!flag[e[i].to])
flag[e[i].to]=,que.push(e[i].to);
}
}
flag[p]=;
}
}
void dfs(int now)
{
for(int i=h[now];i;i=e[i].nex)
{
int to=e[i].to;
if(i%==)
{
if(dis[][now]&&dis[][to])
ans=MAX(ans,dis[][now]+dis[][to]);
}
else
dfs(to);
}
}
bool cmp(edge a,edge b)
{
return id[a.to]==id[b.to]?id[a.nex]<id[b.nex]:id[a.to]<id[b.to];
}
int read()
{
char ch=;int w=;
while(ch<''||ch>''){ch=getchar();}
while(ch>=''&&ch<=''){w=w*+ch-'';ch=getchar();}
return w;
}
int main()
{
r(n),r(m);
for(int i=;i<=m;++i)
r(u),r(to),add(u,to),yuan[i]=(edge){to,u};
for(int i=;i<=n;++i)
if(!dfn[i])
tarjan(i);
for(int i=;i<=n;++i)
w[id[i]]++;
st=id[];
sort(yuan+,yuan+m+,cmp);
memset(h,,sizeof(h));
cnt=;
for(int i=;i<=m;++i)
{
int x=id[yuan[i].nex],y=id[yuan[i].to];
if((x==id[yuan[i-].nex]&&y==id[yuan[i-].to])||(x==y))
continue;
add(x,y),add(y,x);
}
spfa(st,),spfa(st,);
ans=w[st];
dfs(st);
if(ans>w[st]) printf("%d",ans-w[st]);
else printf("%d",ans);
return ;
}
Tarjan水题系列(1):草鉴定Grass Cownoisseur [USACO15JAN]or[luogu P3119]的更多相关文章
- [USACO15JAN]草鉴定Grass Cownoisseur(分层图+tarjan)
[USACO15JAN]草鉴定Grass Cownoisseur 题目描述 In an effort to better manage the grazing patterns of his cows ...
- 洛谷——P3119 [USACO15JAN]草鉴定Grass Cownoisseur
P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 In an effort to better manage the grazing patterns of hi ...
- 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur 解题报告
P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 约翰有\(n\)块草场,编号1到\(n\),这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可 ...
- 【洛谷P3119】[USACO15JAN]草鉴定Grass Cownoisseur
草鉴定Grass Cownoisseur 题目链接 约翰有n块草场,编号1到n,这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可能多的草场去品尝牧草. 贝西总是从1号草场出发,最后 ...
- 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur (SCC缩点,SPFA最长路,枚举反边)
P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 In an effort to better manage the grazing patterns of hi ...
- Tarjan水题系列(5):最大半连通子图 [ZJOI2007 luogu P2272]
题目 大意: 缩点后转为求最长链的长度和最长链的个数 思路: 看懂题就会做系列 长度和个数都可以拓扑排序后DP求得 毕竟是2007年的题 代码: 如下 #include <cstdio> ...
- [USACO15JAN]草鉴定Grass Cownoisseur (分层图,最长路,$Tarjan$)
题目链接 Solution 水水的套路题. 可以考虑到一个环内的点是可以都到达的,所以 \(tajan\) 求出一个 \(DAG\) . 然后 \(DAG\) 上的点权值就是 \(scc\) 的大小. ...
- Tarjan水题系列(4):HAOI2010 软件安装
题目: 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大). ...
- Tarjan水题系列(3):HNOI2006 潘多拉的魔盒
题目: 链接 大意: 盒子与盒子之间的关系构成一个有向图 求图上包含节点数最多的路径的节点数 思路: 有向图上求包含节点数最多的路径的节点数 可直接使用tarjan缩点后拓扑dp求得 在此不赘述 此题 ...
随机推荐
- selenium+键盘鼠标
一.简单操作 1.点击(鼠标左键)页面按钮:click() 2.请空输入框:clear() 3.输入字符串:send_keys() 二.模拟键盘 模拟键盘的操作需要先导入键盘模块:from selen ...
- lines
lines Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- CodeChef-----February Challenge 2018---Broken Clock(极坐标+三角函数递推+矩阵快速幂)
链接: https://www.codechef.com/FEB18/problems/BROCLK Broken Clock Problem Code: BROCLK Chef has a clo ...
- mysql 时间差
SELECT TIMESTAMPDIFF(minute,'2019-01-01 00:00:00', '2019-01-01 01:30:00') 返回结果 90 类推,有 SELECT TIMEST ...
- Future 和 CompletableFuture 异步任务 in Java
Future 异步任务 定义Callable接口的实现 import java.util.concurrent.Callable; public class RealDataCallable impl ...
- SpringBoot 整合Shiro 一指禅
目标 了解ApacheShiro是什么,能做什么: 通过QuickStart 代码领会 Shiro的关键概念: 能基于SpringBoot 整合Shiro 实现URL安全访问: 掌握基于注解的方法,以 ...
- linux下挂载磁盘
1.使用fdisk 查看硬盘信息 [root@localhost ~]# fdisk -l Disk /dev/sdb: 107.4 GB, 107374182400 bytes 255 heads, ...
- DeepFaceLab报错,integer division or modulo by zero
DeepFaceLab的集成环境在众多换脸软件中是做的最好的.但是使用过程也会出现一些错误,主要的错误有两个,一个是你配置太低OOM了,主要体现显存太低.第二个是版本不对应.比如你原先用的cuda9. ...
- JavaScript对象---递归遍历对象
JavaScript 中的所有事物都是对象:字符串.数值.数组.函数... 此外,JavaScript 允许自定义对象. JavaScript 对象 JavaScript 提供多个内建对象,比如 St ...
- springboot打war包部署tomcat服务器,以及表单提交数据乱码处理
小白觉得springboot打成jar包直接使用内嵌的tomcat或jetty容器(java -jar xxx.jar)运行项目不利于定位问题,我还是习惯于查看tomcat或nginx的日志来定位问题 ...