tarjan图论算法

标签: tarjan 图论 模板


洛谷P3387 【模板】缩点



算法:Tarjan有向图强连通分量+缩点+DAGdp

代码:

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
#include <iostream>
#define psk push_back
using namespace std; const int MAXN = 1e5 + 50; int dfn[MAXN], low[MAXN], dfscnt = 0, scccnt = 0;
int sccnum[MAXN], s[MAXN], in[MAXN], top = 0;
int p0[MAXN], p[MAXN], d[MAXN]; vector<int> G[MAXN], G0[MAXN];
queue<int> q; inline int read()
{
int res = 0, f = 1;
char ch;
ch = getchar(); while(!isdigit(ch)){
if(ch == '-')
f = -1; ch = getchar();
} while(isdigit(ch)){
res = res * 10 + ch - 48; ch = getchar();
} return f * res;
}
void tarjan(int now)
{
dfn[now] = low[now] = ++ dfscnt;
s[top ++] = now; for(int i = 0; i < G0[now].size(); i ++){
int v = G0[now][i]; if(!dfn[v]){
tarjan(v);
low[now] = min(low[now], low[v]);
}
else if(!sccnum[v])
low[now] = min(low[now], dfn[v]);
} if(low[now] == dfn[now]){ scccnt ++; do{
sccnum[s[-- top]] = scccnt;
}while(s[top] != now); }
return;
} int topoo()
{ for(int i = 1; i <= scccnt; i ++)
if(!in[i]){
d[i] = p[i];
q.push(i); } while(!q.empty()){
int u = q.front();q.pop(); for(int i = 0; i < G[u].size(); i ++){
int v = G[u][i]; if(d[v] < d[u] + p[v])
d[v] = d[u] + p[v]; in[v] --; if(!in[v])
q.push(v);
}
} return *max_element(d + 1, d + 1 + scccnt);
} int main()
{
int n, m; n = read(), m = read(); for(int i = 1; i <= n; i ++)
p0[i] = read(); for(int i = 0; i < m; i ++){
int u, v; u = read(), v = read(); G0[u].psk(v);
} for(int i = 1; i <= n; i ++)
if(!dfn[i])
tarjan(i); for(int i = 1; i <= n; i ++){
p[sccnum[i]] += p0[i]; for(int j = 0; j < G0[i].size(); j ++){
int v = G0[i][j];
if(sccnum[i] == sccnum[v])
continue;
G[sccnum[i]].psk(sccnum[v]); in[sccnum[v]] ++;
}
} printf("%d", topoo()); return 0;
}

洛谷P3388 【模板】割点(割顶)

算法:tarjan求无向图割点割边

代码:

#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#define pbk push_back
using namespace std; const int MAXN = 1e5 + 50; int dfn[MAXN], low[MAXN], n, m;
int dfscnt = 0, iscut[MAXN]; vector<int> G[MAXN]; inline int read()
{
int res = 0, f = 1; char ch; ch = getchar(); while(!isdigit(ch)){
if(ch == '-')
f = -1; ch = getchar();
} while(isdigit(ch)){
res = (res << 3) + (res << 1) + ch - 48; ch = getchar();
} return f * res;
}
void tarjan(int now, int rt)
{
int chcnt = 0; dfn[now] = low[now] = ++ dfscnt; for(int i = 0; i < G[now].size(); i ++){
int v = G[now][i]; if(!dfn[v]){
tarjan(v, rt);
low[now] = min(low[now], low[v]); if(now == rt)
chcnt ++;
else if(low[v] >= dfn[now])
iscut[now] = 1;
} else
low[now] = min(low[now], dfn[v]);
} if(chcnt >= 2)
iscut[now] = 1;
return;
} int main()
{
int n, m, tot = 0; n = read(), m = read(); for(int i = 0; i < m; i ++){
int u, v; u = read(), v = read(); G[u].pbk(v);
G[v].pbk(u);
} for(int i = 1; i <= n; i ++)
if(!dfn[i])
tarjan(i, i); for(int i = 1; i <= n; i ++)
if(iscut[i])
tot ++;
printf("%d\n", tot);
for(int i = 1; i <= n; i ++)
if(iscut[i])
printf("%d ", i); return 0;
}

求无向图边双连通分量

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
#include <iostream>
#define pbk push_back
using namespace std; const int MAXN = 1e5 + 50; vector<int> G[MAXN], bcc[MAXN]; int low[MAXN], dfn[MAXN], bnum[MAXN], s[MAXN];
int n, m, top = 0, dfscnt = 0, bcnt = 0; inline int read()
{
int res = 0, f = 1;
char ch; ch = getchar(); while(!isdigit(ch)){
if(ch == '-')
f = -1; ch = getchar();
} while(isdigit(ch)){
res = (res << 3) + (res << 1) + ch - 48; ch = getchar();
} return f * res;
}
void tarjan(int now, int fa)
{
dfn[now] = low[now] = ++ bcnt;
s[top ++] = now; int flag = 0;
for(int i = 0; i < G[now].size(); i ++){
int v = G[now][i]; if(v == fa && !flag){
flag = 1;
continue;
} if(!dfn[v]){
tarjan(v, now);
low[now] = min(low[now], low[v]);
}
else if(!bnum[v])
low[now] = min(low[now], dfn[v]);
} if(low[now] == dfn[now]){
bcnt ++; do{
bnum[s[-- top]] = bcnt;
bcc[bcnt].pbk(s[top]);
}while(s[top] != now);
} return ;
}
int main()
{
n = read(), m = read(); for(int i = 0; i < m; i ++){
int u, v; u = read(), v = read(); G[u].pbk(v);
G[v].pbk(u);
} for(int i = 1; i <= n; i ++)
if(!dfn[i])
tarjan(i, 0); printf("%d\n", bcnt); for(int i = 1; i <= bcnt; i ++){ printf("%d ", i); for(int j = 0; j < bcc[i].size(); j ++)
printf("%d ", bcc[i][j]);
printf("\n");
}
return 0;
}

求无向图点双连通分量

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
#include <iostream>
#define pbk push_back
using namespace std; const int MAXN = 1e5 + 50; int low[MAXN], dfn[MAXN], n, m;
int s[MAXN], top = 0, bcnt = 0, dfscnt = 0; vector<int> G[MAXN], bcc[MAXN]; inline int read()
{
int res = 0, f = 1; char ch; ch = getchar(); while(!isdigit(ch)){
if(ch == '-')
f = -1;
ch = getchar();
} while(isdigit(ch)){
res = (res << 3) + (res << 1) + ch - 48; ch = getchar();
} return f * res;
}
void tarjan(int now, int rt)
{
low[now] = dfn[now] = ++ bcnt; s[top ++] = now;
if(now == rt && !G[now].size()){
bcc[++ bcnt].pbk(s[-- top]);
return ;
}
for(int i = 0; i < G[now].size(); i ++){
int v = G[now][i]; if(!dfn[v]){
tarjan(v, rt);
low[now] = min(low[now], low[v]); if(low[v] >= dfn[now]){
do{
bcnt ++; bcc[bcnt].pbk(s[--top]);
}while(s[top] != v); bcc[bcnt].pbk(now);
}
}
else
low[now] = min(low[now], dfn[v]);
}
return; } int main()
{
n = read(), m = read(); for(int i = 0; i < m; i ++){
int u, v;
u = read(), v = read(); G[u].pbk(v);
G[v].pbk(u);
} for(int i = 1; i <= n; i ++){
if(!dfn[i])
tarjan(i, i); } for(int i = 1; i <= bcnt; i ++){
printf("%d ", i);
for(int j = 0; j < bcc[i].size(); j ++)
printf("%d ", bcc[i][j]);
printf("\n");
} return 0;
}

tarjan图论算法的更多相关文章

  1. 图论算法-Tarjan模板 【缩点;割顶;双连通分量】

    图论算法-Tarjan模板 [缩点:割顶:双连通分量] 为小伙伴们总结的Tarjan三大算法 Tarjan缩点(求强连通分量) int n; int low[100010],dfn[100010]; ...

  2. [算法模版]Tarjan爷爷的几种图论算法

    [算法模版]Tarjan爷爷的几种图论算法 前言 Tarjan爷爷发明了很多图论算法,这些图论算法有很多相似之处(其中一个就是我都不会).这里会对这三种算法进行简单介绍. 定义 强连通(strongl ...

  3. NOIp 图论算法专题总结 (2)

    系列索引: NOIp 图论算法专题总结 (1) NOIp 图论算法专题总结 (2) NOIp 图论算法专题总结 (3) 树链剖分 https://oi-wiki.org/graph/heavy-lig ...

  4. LCA问题的ST,tarjan离线算法解法

    一  ST算法与LCA 介绍 第一次算法笔记这样的东西,以前学算法只是笔上画画写写,理解了下,刷几道题,其实都没深入理解,以后遇到新的算法要把自己的理解想法写下来,方便日后回顾嘛>=< R ...

  5. 图论算法-最小费用最大流模板【EK;Dinic】

    图论算法-最小费用最大流模板[EK;Dinic] EK模板 const int inf=1000000000; int n,m,s,t; struct node{int v,w,c;}; vector ...

  6. 图论算法-网络最大流【EK;Dinic】

    图论算法-网络最大流模板[EK;Dinic] EK模板 每次找出增广后残量网络中的最小残量增加流量 const int inf=1e9; int n,m,s,t; struct node{int v, ...

  7. LCA最近公共祖先(Tarjan离线算法)

    这篇博客对Tarjan算法的原理和过程模拟的很详细. 转载大佬的博客https://www.cnblogs.com/JVxie/p/4854719.html 第二次更新,之前转载的博客虽然胜在详细,但 ...

  8. LCA(最近公共祖先)--tarjan离线算法 hdu 2586

    HDU 2586 How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/ ...

  9. 最近公共祖先LCA Tarjan 离线算法

    [简介] 解决LCA问题的Tarjan算法利用并查集在一次DFS(深度优先遍历)中完成所有询问.换句话说,要所有询问都读入后才开始计算,所以是一种离线的算法. [原理] 先来看这样一个性质:当两个节点 ...

随机推荐

  1. jQuery总结01_jq的基本概念+选择器

    jQuery基本概念 学习目标:学会如何使用jQuery,掌握jQuery的常用api,能够使用jQuery实现常见的效果. 为什么要学习jQuery? [01-让div显示与设置内容.html] 使 ...

  2. delphi使用Foxit Quick PDF Library读写pdf文本和图片

    简介: Debenu Quick PDF Library(PDF编程开发工具)提供一套全方位的 PDF API 函数,帮助您快速简便地处理 PDF 文件.从文档属性的基本操作到创建您自己的 PDF 查 ...

  3. 小程序模板template使用介绍

    template(模板):是可以在wxml中引用的代码,就是在wxml中引用公用的wxml类型的代码,它的作用类似于组件,因此这里简单的说明下template与Component (组件)的区别. t ...

  4. C语言程序设计100例之(22):插入排序

    例22  插入排序 问题描述 排序是计算机程序设计中的一种重要操作,它的功能是将一个数据元素或记录的任意序列,重新排列成一个以关键字递增(或递减)排列的有序序列. 排序的方法有很多,简单插入排序就是一 ...

  5. Git教程---由浅入深

    初学者很难找到一个由浅入深,学完后能立刻上手的Git教程 Git用户 V&Git专家 Git是一个工具,是目前世界上最先进的分布式版本控制系统(没有之一). 集中式的版本控制系统  V& ...

  6. leetcode-字符串篇

    Implement strStr() /** * Implement strStr(). *  * Return the index of the first occurrence of needle ...

  7. ubuntu16搭建文件服务器

    这篇记录,如何在ubuntu16 安装 FastDFS 文件服务器,详细步骤 环境依赖 apt-get install make apt-get install unzip apt-get insta ...

  8. table-layout:fixed

    table-layout: fixed; 在table上设置上面属性后,如果不设置td的宽度,那么所有td的宽度平分总table宽度.如果设置了td的宽度,则以设置的宽度为准. table-layou ...

  9. 当h5页面图片加载失败后,给定一个默认图

    本文主要讨论页面中图片加载失败后替换默认图片的几种方式 重点来了:一定要记住error事件不冒泡. 相关的知识点:jquery的ready方法.$("img").error().i ...

  10. java架构之-负载均衡-Ribbon 的使用

    一. 什么是负载均衡负载均衡就是分发请求流量到不同的服务器.负载均衡一般分为两种:1. 服务器端负载均衡(nginx) 2. 客户端负载均衡(Ribbon) 二. spring- - cloud- - ...