8.10-DayT3游走(wander)
题目大意
lue..
题解
先跑一遍tarjan缩点,在新图中加入两个强连通分量之间的边,则此图为一个有向无环图(DAG)。则最终答案为1点所在的强连通分量或包括1点的几个强连通分量的点数之和。
如果为几个强连通分量则由于该图为DAG而题中要求为从1点出发又回到1点,
故路径中一定包含一条反向边。又由于强连同分量中的点彼此强连同,故该反向边一定为两个强连同分量之间的边。
故路径为一条边+一条经过一点所在强连通分量的路径。
图中每个点代表一个强连通分量。其中1为包含1点的强通分量。
其中路径为k-->........3-->1-->2-->4-->......-->n,而反向边为边k-->n
因此,最终答案即为求如上一条包含点最多的路径。
考虑边k-->n,边k-->n一定为缩点后强连通分量之间的边。如果首先求出路径长度则枚举边k-->n即可。而路径长度一定为k-->1的包含点最多的路径长度与1-->n的包含点最多的路径的点的个数之和减1点所在的强连通分量包含的点的个数。
故可以预处理出1点所在的强连通分量到其他强连通分量的路径中最多包含点的个数,再将所有强连通分量间的边反向,求1点所在的强连通分量到其他强连通分量的路径中最多包含点的个数,既求其他强连通分量到1点所在的强连通分量的路径中最多包含点的个数。
最后枚举所有强连通分量之间的边k-->n,答案为 max(f1[n]+f2[k]-size[bel[1]])
注意:当f1或f2为0时不更新答案因为如果为0则代表1点所在的强连通分量
无法到达n点或k点。
Tarjan时间复杂度为O(n+m),两次DAG上求最长路的时间复杂度为O(m)
总体时间复杂度O(n+m)。
(hhh一看就不是我自己写的题解...改不动了hhh)
- #include<stack>
- #include<queue>
- #include<stdio.h>
- #include<string.h>
- #include<algorithm>
- using namespace std;
- #define N 110000
- int n,m,ans;
- int t1,t2,tot,scc,cnt;
- int head[N],to[*N],nex[*N];
- int deep[N],low[N],bel[N],vis[N];
- int ins[N],inq[N],size[N];
- int f1[N],f2[N];
- stack<int>s;
- queue<int>que;
- void add(int x,int y)
- {
- tot++;
- nex[tot]=head[x];
- head[x]=tot;
- to[tot]=y;
- }
- int tot1;
- int head1[N],to1[*N],nex1[*N],from1[*N];
- void add1(int x,int y)
- {
- tot1++;
- nex1[tot1]=head1[x];
- head1[x]=tot1;
- to1[tot1]=y;
- from1[tot1]=x;
- }
- int tot2;
- int head2[N],to2[*N],nex2[*N],from2[*N];
- void add2(int x,int y)
- {
- tot2++;
- nex2[tot2]=head2[x];
- head2[x]=tot2;
- to2[tot2]=y;
- from2[tot2]=x;
- }
- void tarjan(int x)
- {
- deep[x]=low[x]=++cnt;
- ins[x]=;
- vis[x]=;
- s.push(x);
- for(int i=head[x];i;i=nex[i])
- {
- if(ins[to[i]])
- low[x]=min(low[x],deep[to[i]]);
- else if(!vis[to[i]])
- {
- tarjan(to[i]);
- low[x]=min(low[x],low[to[i]]);
- }
- }
- if(deep[x]==low[x])
- {
- scc++;
- int tmp=s.top();
- s.pop();
- size[scc]++;
- bel[tmp]=scc;
- ins[tmp]=;
- while(tmp!=x)
- {
- tmp=s.top();
- s.pop();
- size[scc]++;
- ins[tmp]=;
- bel[tmp]=scc;
- }
- }
- }
- int main()
- {
- freopen("wander.in","r",stdin);
- freopen("wander.out","w",stdout);
- scanf("%d%d",&n,&m);
- for(int i=;i<=m;i++)
- {
- scanf("%d%d",&t1,&t2);
- add(t1,t2);
- }
- for(int i=;i<=n;i++)
- {
- if(!vis[i])
- {
- cnt=;
- tarjan(i);
- }
- }
- for(int i=;i<=n;i++)
- {
- for(int j=head[i];j;j=nex[j])
- if(bel[i]!=bel[to[j]])
- {
- add1(bel[i],bel[to[j]]);
- add2(bel[to[j]],bel[i]);
- }
- }
- que.push(bel[]);
- f1[bel[]]=size[bel[]];
- inq[bel[]]=;
- while(!que.empty())
- {
- int tmp=que.front();
- que.pop();
- inq[tmp]=;
- for(int i=head1[tmp];i;i=nex1[i])
- if(f1[to1[i]]<f1[tmp]+size[to1[i]])
- {
- f1[to1[i]]=f1[tmp]+size[to1[i]];
- if(!inq[to1[i]])
- {
- inq[to1[i]]=;
- que.push(to1[i]);
- }
- }
- }
- memset(inq,,sizeof(inq));
- que.push(bel[]);
- inq[bel[]]=;
- f2[bel[]]=size[bel[]];
- while(!que.empty())
- {
- int tmp=que.front();
- que.pop();
- inq[tmp]=;
- for(int i=head2[tmp];i;i=nex2[i])
- if(f2[to2[i]]<f2[tmp]+size[to2[i]])
- {
- f2[to2[i]]=f2[tmp]+size[to2[i]];
- if(!inq[to2[i]])
- {
- inq[to2[i]]=;
- que.push(to2[i]);
- }
- }
- }
- ans=max(ans,size[bel[]]);
- for(int i=;i<=tot2;i++)
- if(f2[to2[i]]&&f1[from2[i]])
- {
- if(f2[to2[i]]+f1[from2[i]]-size[bel[]]>ans)
- ans=f2[to2[i]]+f1[from2[i]]-size[bel[]];
- }
- printf("%d",ans);
- return ;
- }
std太强了
8.10-DayT3游走(wander)的更多相关文章
- 【BZOJ-3143】游走 高斯消元 + 概率期望
3143: [Hnoi2013]游走 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2264 Solved: 987[Submit][Status] ...
- 3143: [Hnoi2013]游走 - BZOJ
Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点, ...
- bzoj 3143: [Hnoi2013]游走 高斯消元
3143: [Hnoi2013]游走 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1026 Solved: 448[Submit][Status] ...
- 数学(概率):HNOI2013 游走
[题目描述] 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这 ...
- 介绍一个全局最优化的方法:随机游走算法(Random Walk)
1. 关于全局最优化求解 全局最优化是一个非常复杂的问题,目前还没有一个通用的办法可以对任意复杂函数求解全局最优值.上一篇文章讲解了一个求解局部极小值的方法--梯度下降法.这种方法对于求解精度不高 ...
- [补档][Hnoi2013]游走
[Hnoi2013]游走 题目 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一 ...
- 游走[HNOI2013]
[题目描述] 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这 ...
- bzoj 3143: [Hnoi2013]游走
Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点, ...
- BZOJ 3143: [Hnoi2013]游走 [概率DP 高斯消元]
一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分 ...
随机推荐
- Keras 回归 拟合 收集
案例1 from keras.models import Sequential from keras.layers import Dense, LSTM, Activation from keras. ...
- 《深入理解java虚拟机》读书笔记十——第十一章
第十一章 晚期(运行期)优化 1.HotSpot虚拟机内的即时编译 解释器与编译器: 许多Java虚拟机的执行引擎在执行Java代码的时候都有解释执行(通过解释器执行)和编译执行(通过即时编译器产生 ...
- Codeforce 515A - Drazil and Date
Someday, Drazil wanted to go on date with Varda. Drazil and Varda live on Cartesian plane. Drazil's ...
- WSO2 ESB XML定义语法(2)
5.Proxy Service 配置 <proxy>元素用于定义Synapse代理服务. 通过基础Axis2引擎在指定的传输上创建和公开代理服务,根据标准的Axis2约定(即基于服务名称) ...
- PP: Shallow RNNs: a method for accurate time-series classification on tiny devices
Problem: time series classification shallow RNNs: the first layer splits the input sequence and runs ...
- [JSOI2010]快递服务
Description Luogu4046 BZOJ1820 Solution 暴力DP很好想,\(f[i][j][k][l]\)表示处理到第\(i\)个任务,三个人在\(i,j,k\)的方案数.显然 ...
- 解决jquery.pjax加载后的异常滚动
个人博客 地址:http://www.wenhaofan.com/article/20181106154356 在使用jquery.pjax的时候发现每次加载完成后都会将滚动条滚动至顶部,用户体验极不 ...
- AcWing 1019. 庆功会 多重背包求max
//多重背包 max #include <iostream> using namespace std; ; int n, m; int f[N]; int main() { cin > ...
- docker 免sudo设置(仅3个命令)
首先,下载docker, 需3话: sudo apt install docker.io sudo systemctl start docker sudo systemctl enable docke ...
- java继承与多态课后作业
1.动手实验 源码 class Grandparent { public Grandparent() { System.out.println("GrandPar ...