[Luogu P3119] [USACO15JAN]草鉴定Grass Cownoisseur (缩点+图上DP)
题面
传送门:https://www.luogu.org/problemnew/show/P3119




Solution
这题显然要先把缩点做了。
然后我们就可以考虑如何处理走反向边的问题。
像我这样的蒟蒻,当然是使用搜索,带记忆化的那种(滑稽)。
考虑设f(i,j)表示到达第i个点,还能走j次反向边,所能到达的最多的点的数量。
转移可以表示为:

如果x能到达1所在的强连通分量或max出来的值不为0,说明当前状态可行,否则不可行。
然后用记忆化搜索表达出来就OK了
Code
#include<iostream>
#include<cstdio>
#include<vector>
#include<stack>
#include<cstring>
using namespace std;
long long read()
{
long long x=0,f=1; char c=getchar();
while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
const int N=100000+100;
struct road
{
int to,IsBack;
road (int A,int B)
{
to=A,IsBack=B;
}
};
vector <int> e[N];
vector <road> e2[N];
int belong[N],nd_tot,nd_to,low[N],dfn[N],InStack[N],cnt[N];
stack <int> st;
void Tarjan(int now)
{
low[now]=dfn[now]=++nd_to;
InStack[now]=true;
st.push(now);
for(int i=0;i<int(e[now].size());i++)
if(dfn[e[now][i]]==0)
{
Tarjan(e[now][i]);
low[now]=min(low[now],low[e[now][i]]);
}
else if(InStack[e[now][i]]==true)
low[now]=min(low[now],low[e[now][i]]);
if(low[now]==dfn[now])
{
nd_tot++;
while(st.empty()==false)
{
int temp=st.top();
st.pop();
belong[temp]=nd_tot;
InStack[temp]=false;
cnt[nd_tot]++;
if(temp==now)
break;
}
}
}
int n,m,S,f[N][2];
int dfs(int now,int back)
{
if(f[now][back]>=0) return f[now][back];
int t_ans=0;
bool OK=false;
for(int i=0;i<int(e2[now].size());i++)
if(e2[now][i].to!=S and back-e2[now][i].IsBack>=0)
t_ans=max(t_ans,dfs(e2[now][i].to,back-e2[now][i].IsBack));
else if(back>=e2[now][i].IsBack)
OK=true;
if(t_ans!=0 or OK==true)
return f[now][back]=t_ans+cnt[now];
else
return f[now][back]=0;
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++)
e[i].reserve(4),
e2[i].reserve(4);
for(int i=1;i<=m;i++)
{
int s=read(),t=read();
e[s].push_back(t);
} for(int i=1;i<=n;i++)
if(dfn[i]==0)
Tarjan(i);
S=belong[1];
for(int i=1;i<=n;i++)
for(int j=0;j<int(e[i].size());j++)
if(belong[i]!=belong[e[i][j]])
{
e2[belong[i]].push_back(road(belong[e[i][j]],0));
e2[belong[e[i][j]]].push_back(road(belong[i],1));
} memset(f,0x80,sizeof f);
int ans=0;
for(int i=0;i<int(e2[S].size());i++)
ans=max(ans,dfs(e2[S][i].to,1-e2[S][i].IsBack)); printf("%d",ans+cnt[S]);
return 0;
}
C++(正解)
[Luogu P3119] [USACO15JAN]草鉴定Grass Cownoisseur (缩点+图上DP)的更多相关文章
- luogu P3119 [USACO15JAN]草鉴定Grass Cownoisseur
题目描述 In an effort to better manage the grazing patterns of his cows, Farmer John has installed one-w ...
- 洛谷 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 解题报告
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 ...
- [USACO15JAN]草鉴定Grass Cownoisseur(分层图+tarjan)
[USACO15JAN]草鉴定Grass Cownoisseur 题目描述 In an effort to better manage the grazing patterns of his cows ...
- Luogu 3119 [USACO15JAN]草鉴定Grass Cownoisseur
思路很乱,写个博客理一理. 缩点 + dp. 首先发现把一个环上的边反向是意义不大的,这样子不但不好算,而且相当于浪费了一次反向的机会.反正一个强连通分量里的点绕一遍都可以走到,所以我们缩点之后把一个 ...
- P3119 [USACO15JAN]草鉴定Grass Cownoisseur
题目描述 In an effort to better manage the grazing patterns of his cows, Farmer John has installed one-w ...
- 洛谷—— P3119 [USACO15JAN]草鉴定Grass Cownoisseur || BZOJ——T 3887: [Usaco2015 Jan]Grass Cownoisseur
http://www.lydsy.com/JudgeOnline/problem.php?id=3887|| https://www.luogu.org/problem/show?pid=3119 D ...
- P3119 [USACO15JAN]草鉴定Grass Cownoisseur 分层图或者跑两次最长路
https://www.luogu.org/problemnew/show/P3119 题意 有一个有向图,允许最多走一次逆向的路,问从1再走回1,最多能经过几个点. 思路 (一)首先先缩点.自己在缩 ...
随机推荐
- Linux系统编程 —时序竞态
时序竞态 什么是时序竞态?将同一个程序执行两次,正常情况下,前后两次执行得到的结果应该是一样的.但由于系统资源竞争的原因,前后两次执行的结果有可能得到不一样的结果,这个现象就是时序竞态. pause函 ...
- DIV垂直滚动效果源码
<div id="demo" style="width: 300; overflow: hidden; line-height:24px; height: 100p ...
- 【奇淫巧技】XSS绕过技巧
XSS记录 1.首先是弹窗函数: alert(1) prompt(1) confirm(1)eval() 2.然后是字符的编码和浏览器的解析机制: 要讲编码绕过,首先我们要理解浏览器的解析过程,浏览器 ...
- vue中,使用 es6的 ` 符号给字符串之间换行
我这里分功能是点击"复制范围",就相当于复制图上的坐标点一样的数据和格式: "复制功能"的代码如下: copyPoints() { const vm = thi ...
- CodeForces 79D 【Password】,洛谷P3943 【星空】
其实我做的是洛谷的P3943,但是听说fstqwq窃题...... 题目描述: 小 C 拿来了一长串星型小灯泡,假装是星星,递给小 F,想让小 F 开心一点.不过,有 着强迫症的小 F 发现,这串一共 ...
- 解决mvn clean install的报错The packaging for this project did not assign a file to the build artifact
解决mvn clean install的报错The packaging for this project did not assign a file to the build artifact
- CAD& CG 2020 胡事民教授—开源框架Jittor的创新与探索
题目:深度学习框架"计图"的创新与探索 报告人:胡事民 报告人简介:胡事民,清华大学计算机系教授,主要研究方向为计算机图形学.虚拟现实.智能信息处理和系统软件等. 报告简介:深度学 ...
- vscode 插件保存记录
- [Docker] redis 全配置
启动容器,加载配置文件并持久化数据 docker run -d --privileged=true -p 6379:6379 --restart always -v /usr/redis/conf:/ ...
- 多测师讲解——python002.2练习题
# # 作业:第二天# ## # 1.求出1 / 1 + 1 / 3 + 1 / 5--+1 / 99的和 (1分之一+1分之三+1分支5....)# # 2.用循环语句,计算2 - 10之间整数的循 ...