tarjan 求强连通分量:

#include<cstdio>
#include<iostream>
#include<cstdlib>
#define N 1000000
#include<vector>
vector <int> scc;
int sta[N],dfn[N],low[N],in[N],tar[N],tot,tp,cnt;
void tarjan(int x)
{
dfn[x]=low[x]=++tot;
sta[++tp]=x;
in[x]=1;
for(int i=head[x];i;i=e[i].nxt)
{
if(!dfn[e[i].to])
{
tarjan(e[i].to);
low[x]=min(low[x],low[e[i].to]);
}
else if(in[e[i].to])
{
low[x]=min(low[x],dfn[e[i].to]);
}
}
if(dfn[x]==low[x])
{
int y;
cnt++;
do{
y=sta[tp--];
in[y]=0;
tar[y]=cnt;
scc[cnt].push_back(y);
}while(x!=y);
}
}

tarjan缩点:

  拓扑排序的思想

代码:

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<queue>
#define N 100000
using namespace std;
int in[N],dfn[N],low[N],sta[N],tot,tp,cnt,nmb,head[N],nmb2;
int n,m,p[N],h[N],tar[N],inn[N],dist[N];
struct node{
int to,nxt,from;
}e[N<<1],e2[N<<1];
void add(int from,int to)
{
e[++nmb]= (node) {to,head[from],from};
head[from]=nmb;
}
void add2(int from,int to)
{
e2[++nmb2]= (node) {to,h[from],from};
h[from]=nmb2;
}
void tarjan(int x)
{
dfn[x]=low[x]=++tot;
sta[++tp]=x;
in[x]=1;
for(int i=head[x];i;i=e[i].nxt)
{
int v=e[i].to;
if(!dfn[v])
{
tarjan(v);
low[x]=min(low[x],low[v]);
}
else if(in[v])
{
low[x]=min(low[x],dfn[v]);
}
}
if(dfn[x]==low[x])
{
int y;
while(y=sta[tp--])
{
tar[y]=x;
in[y]=0;
if(x==y)break;
p[x]+=p[y];
}
}
}
int topo()
{
queue <int> q;
for(int i=1;i<=n;i++)
if(tar[i]==i&&!inn[i])
{
q.push(i);
dist[i]=p[i];
}
while(q.size())
{
int x=q.front();
q.pop();
for(int i=h[x];i;i=e2[i].nxt)
{
int y=e2[i].to;
dist[y]=max(dist[x]+p[y],dist[y]);
inn[y]--;
if(inn[y]==0)q.push(y);
}
}
int ans=0;
for(int i=1;i<=n;i++)ans = max(ans,dist[i]);
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&p[i]);
for(int i=1,x,y;i<=m;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
}
for(int i=1;i<=n;i++) if(!dfn[i])tarjan(i);
for(int i=1;i<=m;i++)
{
int x=tar[e[i].from] , y=tar[e[i].to];
if(x!=y)
{
add2(x,y);
inn[y]++;
}
}
printf("%d\n",topo());
return 0;
}

  

透彻tarjan的更多相关文章

  1. HDOJ迷宫城堡(判断强连通 tarjan算法)

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...

  2. LCA 最近公共祖先 tarjan离线 总结 结合3个例题

    在网上找了一些对tarjan算法解释较好的文章 并加入了自己的理解 LCA(Least Common Ancestor),顾名思义,是指在一棵树中,距离两个点最近的两者的公共节点.也就是说,在两个点通 ...

  3. tarjan算法--求解无向图的割点和桥

    1.桥:是存在于无向图中的这样的一条边,如果去掉这一条边,那么整张无向图会分为两部分,这样的一条边称为桥 也就是说 无向连通图中,如果删除某边后,图变成不连通,则称该边为桥 2.割点:无向连通图中,如 ...

  4. tarjan 算法应用

    主要讲证明,流程倒是也有 然后发现自己并不会严谨证明 其实后面一些部分流程还是挺详细 本来这篇blog叫做"图论部分算法证明",然后发现OI中的图论想完全用数学上的方法证明完全超出 ...

  5. HDU4738 tarjan割边|割边、割点模板

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=4738 坑点: 处理重边 图可能不连通,要输出0 若求出的结果是0,则要输出1,因为最少要派一个人 #inc ...

  6. bzoj 1179[Apio2009]Atm (tarjan+spfa)

    题目 输入 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号.接下来N行,每行一 ...

  7. tarjan讲解(用codevs1332(tarjan的裸题)讲解)

    主要借助这道比较裸的题来讲一下tarjan这种算法 tarjan是一种求解有向图强连通分量的线性时间的算法.(用dfs来实现) 如果两个顶点可以相互通达,则称两个顶点强连通.如果有向图G的每两个顶点都 ...

  8. NOIP2009最优贸易[spfa变形|tarjan 缩点 DP]

    题目描述 C 国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市.任意两个 城市之间最多只有一条道路直接相连.这 m 条道路中有一部分为单向通行的道路,一部分 为双向通行的道路 ...

  9. Tarjan

    //求强连通分量 void uni(int x,int y){ if (rank[x]<rank[y]){ fa[x]=y; size[y]+=size[x]; }else{ rank[x]+= ...

随机推荐

  1. centos8自定义目录安装php7.3

    1.目录结构 源码目录:/home/werben/pkgsrc/php-7.3.11 安装目录:/home/werben/application/php7.3.11 2.下载php源码 # 官网地址: ...

  2. 用pandas库对csv文件中的文本数据进行分析处理

    #数据分析 import pandas import csv old_path = r'd:\2000W\200W-400W.csv' f = open(old_path,'r',encoding=' ...

  3. [Tarjan系列] Tarjan算法求无向图的桥和割点

    RobertTarjan真的是一个传说级的大人物. 他发明的LCT,SplayTree这些数据结构真的给我带来了诸多便利,各种动态图论题都可以用LCT解决. 而且,Tarjan并不只发明了LCT,他对 ...

  4. hdu 1068 最大子序列和变形,,,

    #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #d ...

  5. JS中逗号运算符的用法

    逗号运算符,它将先计算左边的参数,再计算右边的参数值.然后返回最右边参数的值. 原书举的例子不太好,无法解释上面那句话,这里另外提供一个: var a = 10, b = 20; function C ...

  6. 原生 JS 绑定事件 移除事件

    监听事件的绑定与移除主要是addEventListener和removeEventListener的运用. addEventListener语法 element.addEventListener(ty ...

  7. python之random库的使用以及程序的异常处理

    1.random库的使用: random库是使用随机数的Python标准库从概率论角度来说,随机数是随机产生的数据(比如抛硬币),但时计算机是不可能产生随机值,真正的随机数也是在特定条件下产生的确定值 ...

  8. python之字符串类型的格式化

    python之字符串类型的格式化 要点:python字符串通过format()方法进行格式化处理.(Python语言同时支持两种字符串格式化方法,一种类似C语言中printf()函数的格式化方法,支持 ...

  9. ESP8266 AT指令

    无线网络名称 ESP_XXXXXX,后面的数字是MAC地址后几位 应用模式: AT+CWMODE? //查询 AT+CWMODE=<mode> //设置(重启后生效).1-Station模 ...

  10. DataTable序列化及反序列化Json

    添加Json解析引用 using Newtonsoft.Json; 实现方式一:普通转换 private void button1_Click(object sender, EventArgs e) ...