tarjan 缩点
来源:互联网 发布:mac视频播放器下载 编辑:程序博客网 时间:2024/06/05 07:43
tarjan啊(⊙o⊙)…
嗯。。我的理解可能比较诡异
先说缩点:
洛谷P3387 的模板
题目描述
给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大。你只需要求出这个权值和。
允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次。
输入格式:
第一行,n,m
第二行,n个整数,依次代表点权
第三至m+2行,每行两个整数u,v,表示u->v有一条有向边
输出格式:
共一行,最大的点权之和。
最后的树形dp就先忽略,先只说缩点
需要缩点的时候我们确实一看就知道,但是像我这种啥模板也没写过的
就开始纠结怎么缩点了
先要理解核心的两个数组的本质(⊙o⊙)…
所谓dfn[ ]时间戳,就是记录一下你搜到这个点的时间
然后low[ ],应该可以说是你从这个点继续往下走,如果有环的话你是会回到之前你走的那个点的,那么low[ ]的值就是你可以回到的最早的那个点的dfn[ ]
然后是赋值
dfn[ ]好说,一搜进来就给一个dfn[ ]=++time;
low[ ]的话{ (to就是遍历边的那个连接的下一个的点)
if( !dfn[to] ) tarjan(to) , low[pos] = min( low[pos] , low[to] )
else if( vis[to] ) low[pos] = min( low[pos] , dfn[to] )
}(vis 是一个入栈的标记)
也就是说有分两种情况
第一种情况:如果你还没有对to进行过任何处理,那你就得先进去看看了2333
第二种情况:如果to已经被你搞过了,这个时候你的low可不能跟着他的low跑,那样你可能跟着他跑到别的环里面去。 如果它已经跟着别人组成一个环缩成一个点了,那它就不在栈内,那你肯定不能和它缩成一个点,只能自己新建一个团队了。所以只有(vis[to])的时候你才能跟着他赋值。
不难想出在我们这样的处理之后如果仍然有(low[pos]==dfn[pos])
那么我们从最后一个入栈的点一个一个往出取,直到们取到pos,那么这些取出来的点将来一定是同一个点,这个时候我们就可以用一些很基础的方法把它们记录在一起了
嗯》。。。这里先就只放核心代码吧:
void tarjan(int pos){ dfn[pos]=low[pos]=++tim; stack[++top]=pos;vis[pos]=true; for(int i=head[pos],v=edge[i].to;i;i=edge[i].nex,v=edge[i].to) if(!dfn[v]) tarjan(v),low[pos]=min(low[pos],low[v]); else if(vis[v]) low[pos]=min(low[pos],dfn[v]); if(low[pos]==dfn[pos]){ ++tot;vis[pos]=false; while(stack[top+1]!=pos){ zz[stack[top]]=tot; vis[stack[top]=false; top--; } }}int main(){ for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);}
- poj1904 tarjan缩点
- HDU3836 Tarjan缩点
- HDU3836(tarjan+缩点)
- 1827 tarjan+缩点
- tarjan+缩点
- tarjan + 缩点
- Tarjan缩点
- POJ1236----tarjan缩点
- tarjan+缩点
- hdu5934 Tarjan 缩点
- poj2186--tarjan+缩点
- hdu5934(tarjan缩点)
- Tarjan缩点模板
- 图论--tarjan缩点
- tarjan 缩点
- Tarjan 缩点
- Tarjan缩点
- tarjan缩点
- web复选框的传值问题
- 线程之间的通信
- Differential privacy
- Web static server
- 深入理解java对象序列化
- tarjan 缩点
- 为什么java程序要public static void main(String[ ] args)方法
- 逆波兰表达式递归求值
- Servlet之文件上传与下载
- 无线视频传输任务的进展与问题
- 171003 逆向-Reversing.kr(CSHOP)
- ES6(五: Array扩展)
- 四、Java基础类库
- java将图片灰度化