题目如下:

约翰有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]的更多相关文章

  1. [USACO15JAN]草鉴定Grass Cownoisseur(分层图+tarjan)

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

  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 解题报告

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

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

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

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

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

  6. Tarjan水题系列(5):最大半连通子图 [ZJOI2007 luogu P2272]

    题目 大意: 缩点后转为求最长链的长度和最长链的个数 思路: 看懂题就会做系列 长度和个数都可以拓扑排序后DP求得 毕竟是2007年的题 代码: 如下 #include <cstdio> ...

  7. [USACO15JAN]草鉴定Grass Cownoisseur (分层图,最长路,$Tarjan$)

    题目链接 Solution 水水的套路题. 可以考虑到一个环内的点是可以都到达的,所以 \(tajan\) 求出一个 \(DAG\) . 然后 \(DAG\) 上的点权值就是 \(scc\) 的大小. ...

  8. Tarjan水题系列(4):HAOI2010 软件安装

    题目: 现在我们的手头有N个软件,对于一个软件i,它要占用Wi​的磁盘空间,它的价值为Vi​.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi​的和最大). ...

  9. Tarjan水题系列(3):HNOI2006 潘多拉的魔盒

    题目: 链接 大意: 盒子与盒子之间的关系构成一个有向图 求图上包含节点数最多的路径的节点数 思路: 有向图上求包含节点数最多的路径的节点数 可直接使用tarjan缩点后拓扑dp求得 在此不赘述 此题 ...

随机推荐

  1. The Preliminary Contest for ICPC Asia Shanghai 2019 D. Counting Sequences I

    题目:https://nanti.jisuanke.com/t/41412思路:dfs           先取ai>2  2^12>3000 因此至多取11个 其余用1补        ...

  2. 【学习小记】Berlekamp-Massey算法

    Preface BM算法是用来求一个数列的最短线性递推式的. 形式化的,BM算法能够对于长度为n的有穷数列或者已知其满足线性递推的无穷数列\(a\),找到最短的长度为m的有穷数列\(c\),满足对于所 ...

  3. [模板][快速排序&归并排序]

    不得不说,手写的快排真的好菜.(即使开了随机数...) 快速排序 #include<iostream> #include<cstdio> #include<cstring ...

  4. C和C++中的副本机制

    函数的形参.return 都有副本机制.数组没有副本机制 (为了节约内存) 函数形参和局部变量的生命周期.函数调用结束后就会被回收.

  5. 在Java web模板的上进行编写

    要求: 链接:https://pan.baidu.com/s/15NdAt-aiv-X9sRbMSfXYXQ 提取码:7agw web模板: 链接:https://pan.baidu.com/s/1A ...

  6. SWPU2019 伟大的侦探

    01editor 选择 EBCDIC编码得到压缩包的密码 这里用到的是福尔摩斯里面的跳舞的小人加密 结果是:iloveholmesandwllm

  7. IT界须知的故事——仙童八叛徒

    原文:http://blog.sina.com.cn/s/blog_457012450100vnbl.html 许多电脑史学家都认为,要想了解美国硅谷的发展史,就必须了解早期的仙童半导体公司.这家公司 ...

  8. Maven构建生命周期

    以下引用官方的生命周期解释https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html: 一.构建生命 ...

  9. ros the public key is not available

    W: An error occurred during the signature verification. The repository is not updated and the previo ...

  10. 在JavaScript中引用类型和值类型的区别

    一.存储方式不一样 基本数据类型 变量存储的是简单的数据段,存储的是具体的值,是轻量级的数据存储方式 引用类型 引用类型的值,可以由多个值构成的对象,引用类型的变量存储的是对象引用地址.引用类型是重量 ...