tarjan 算法求强连通分量
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int P=1e6;
const int N=2e6+;
const int M=2e6+;
const int inf=0x3f3f3f3f;
struct edge
{
int f,t,next;
ll v;
}e[M];
int n,m,tot,all,s,cnt,head[N],dfn[N],low[N],st[N],id[N];
int dindex;
bool inst[N];
ll num[N],sum[],val[N];
void add(int f,int t,ll v)
{
e[tot].f=f; e[tot].t=t; e[tot].v=v;
e[tot].next=head[f]; head[f]=tot++;
}
void tarjan(int v)
{
dindex++;
dfn[v]=low[v]=dindex;
st[all++]=v; inst[v]=true;
for(int i=head[v];~i;i=e[i].next)
{
int nx=e[i].t;
if(!dfn[nx])
{
tarjan(nx);
low[v]=min(low[v],low[nx]);
}
else if(inst[nx]) low[v]=min(low[v],dfn[nx]);
}
if(dfn[v]==low[v])
{
cnt++;
while()
{
int cur=st[--all];
inst[cur]=false;
id[cur]=cnt;
if(cur==v) break;
}
}
}
ll work(ll x)
{
ll ans=;
int item=lower_bound(num,num+,x)-num;
ans-=sum[item];
ans+=x*(item+);
ans+=num[item]-x;
return ans;
}
ll dfs(int v)
{
ll res=;
dfn[v]=;
for(int i=head[v];~i;i=e[i].next)
{
int nx=e[i].t;
if(!dfn[nx]) res=max(res,e[i].v+dfs(nx));
else res=max(res,val[nx]+e[i].v);
}
val[v]+=res;
return val[v];
}
int main()
{
num[]=; cnt=; all=; tot=; dindex=;
for(int i=;i<=;i++) num[i]=num[i-]+i,sum[i]=sum[i-]+num[i];
memset(head,-,sizeof(head));
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
int f,t; ll v;
scanf("%d%d%lld",&f,&t,&v);
add(f,t,v);
}
scanf("%d",&s);
tarjan(s);
int up=tot;
for(int i=;i<up;i++)
{
int a=e[i].f,b=e[i].t;
if(!id[a] || !id[b]) continue;
if(id[a]==id[b]) val[id[a]+P]+=work(e[i].v);
else if(id[a]<id[b]) add(id[b]+P,id[a]+P,e[i].v);
else add(id[a]+P,id[b]+P,e[i].v);
}
ll ans=dfs(id[s]+P);
printf("%lld\n",ans);
return ;
}
tarjan 算法求强连通分量的更多相关文章
- HDU 1269 迷宫城堡 tarjan算法求强连通分量
基础模板题,应用tarjan算法求有向图的强连通分量,tarjan在此处的实现方法为:使用栈储存已经访问过的点,当访问的点离开dfs的时候,判断这个点的low值是否等于它的出生日期dfn值,如果相等, ...
- Tarjan 算法求 LCA / Tarjan 算法求强连通分量
[时光蒸汽喵带你做专题]最近公共祖先 LCA (Lowest Common Ancestors)_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili tarjan LCA - YouTube Tarj ...
- [学习笔记] Tarjan算法求强连通分量
今天,我们要探讨的就是--Tarjan算法. Tarjan算法的主要作用便是求一张无向图中的强连通分量,并且用它缩点,把原本一个杂乱无章的有向图转化为一张DAG(有向无环图),以便解决之后的问题. 首 ...
- 【算法】Tarjan算法求强连通分量
概念: 在有向图G中,如果两个定点u可以到达v,并且v也可以到达u,那么我们称这两个定点强连通. 如果有向图G的任意两个顶点都是强连通的,那么我们称G是一个强连通图. 一个有向图中的最大强连通子图,称 ...
- tarjan算法求强连通分量
先上代码: #include <iostream> #include <cstring> #include <vector> #include <stack& ...
- Tarjan算法分解强连通分量(附详细参考文章)
Tarjan算法分解强连通分量 算法思路: 算法通过dfs遍历整个连通分量,并在遍历过程中给每个点打上两个记号:一个是时间戳,即首次访问到节点i的时刻,另一个是节点u的某一个祖先被访问的最早时刻. 时 ...
- kosaraju算法求强连通分量
什么是强连通分量?在这之前先定义一个强连通性(strong connectivity)的概念:有向图中,如果一个顶点s到t有一条路径,t到s也有一条路径,即s与t互相可达,那么我们说s与t是强连通的. ...
- Tarjan模板——求强连通分量
Tarjan求强连通分量的流程在这个博客讲的很清楚,再加上我也没理解透,这里就不写了. 缩点:将同一个连通块内的点视为同一个点. 扔一道模板题:codeVS2822爱在心中 第一问很显然就是求点数大于 ...
- tarjan算法(强连通分量 + 强连通分量缩点 + 桥(割边) + 割点 + LCA)
这篇文章是从网络上总结各方经验 以及 自己找的一些例题的算法模板,主要是用于自己的日后的模板总结以后防失忆常看看的, 写的也是自己能看懂即可. tarjan算法的功能很强大, 可以用来求解强连通分量, ...
随机推荐
- CSS魔法(一) 盒子模型
序言 盒子模型(橘子橘子皮) 一个盒子,包括:外边距(margin).边框(border).内边距(padding)以及最中间的内容(content). margin.padding <styl ...
- 无线DOS攻击
1.无线连接状态 IEEE 802.11定义了一种客户端状态机制,用于跟踪工作站身份验证和关联状态.无线客户端和AP基于IEEE标准实现这种状态机制.成功关联的客户站停留在状态3,才能进行无线通信.处 ...
- JS执行一次任务与定期任务与清除执行
1.一次性任务的执行与清除执行 1.定期执行 <script> timer = 0; timer = setTimeout(function() { console.log("s ...
- 数组Array的一些方法
数组对象属性和方法的概述:1> arr.push() 将参数添加至数组的末尾,返回的是新数组的长度2> arr.unshift() 将参数添加到数组的开头,返回新数组的长度3> ar ...
- k64 datasheet学习笔记4---Memory Map
1.前言 本文主要介绍K64地址空间的映射 2. System Memory Map 3. K64地址映射 4. Armv7m地址映射 4.1 Armv7M.System地址段(0XE0000000~ ...
- HTMl学习笔记02-编辑器
工欲善其事,必先利其器 使用专业HTML编辑器来编辑HTML,推荐使用Notepad++,中文界面. 在Notepad++安装完成后,点击文件>新建.语言>H中选择HTML 在新建的文件输 ...
- 【转】assert预处理宏与预处理变量
assert assert是一个预处理宏,由预处理器管理而非编译器管理,所以使用时都不用命名空间声明,如果你写成std::assert反而是错的.使用assert需要包含cassert或assert. ...
- C++:__stdcall详解
原文地址:http://www.cnblogs.com/songfeixiang/p/3733661.html 对_stdcall 的理解(上)在C语言中,假设我们有这样的一个函数:int funct ...
- JavaScript——封装
封装:使用对象封装的好处是可以减少全局变量污染的机会,讲属性,函数都隶属一个对象. 封装前: <script> var name="foo"; //name是全局的,被 ...
- PYTHON-文件处理-练习
## 一.实现用户注册功能# 思路:# 用户输入用户名.密码# 将用户输入的内容按照固定的格式,比如:egon:123,存入文件# 可以往一个文件中重复注册新的用户名和密码# 附加:# 1.对输入的用 ...