Tarjan 模板,高级并查集
第一个模板有误!!!!
请见谅!!!
要怪就怪HDU吧,竟然让我过了
第二个模板是正确的。请翻到下面看更新
HDU 1269
评论区居然有人说用并查集过了,其实回想一下
求无向图的连通分量,就是并查集,求有向图的话,就要用到这个算法,或者Kosaraju。
再回想一下,Tarjan确实比较像并查集,我在第一次写的时候就有这种感觉
请看:

这是我在找强连通分量的数量,而在并查集里面,就是:

这样看来,其实,low的含义就是这个f[i],而由于有向图有其顺序的,所以用num[i]记录其访问的顺序。。。。。
无论是代码,还是算法,Tarjan都像极了并查集,不得不说,Trajan其实就是一个高级并查集算法
下面贴下我的模板,这个模板只是过了HDU 1269,看discuss数据比较水,不是太敢确定模板的正确性
说明:num记录访问的顺序,book记录是否访问过,low--按并查集的说法,就是更新它的爸爸,直到它的祖宗(想一下整个算法,确实如此)
有机会看一下这个吧,他写的蛮好的,我就是看了这个才看懂
https://blog.csdn.net/mengxiang000000/article/details/51672725
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
vector<int>u[];
bool book[];
int index;
int num[],low[];
void Tarjan_dfs(int t)
{
index++;book[t]=true;
low[t]=num[t]=index;
for(int i=;i<u[t].size();i++){
if(!book[u[t][i]]){
Tarjan_dfs(u[t][i]);
}
low[t]=min(low[t],low[u[t][i]]);
}
} int main()
{
int n,m;
while(cin>>n>>m&&n&&m){
int x,y;
index=;
memset(book,,sizeof(book));
for(int i=;i<m;i++){
cin>>x>>y;
u[x].push_back(y);
}
for(int i=;i<=n;i++){
if(!book[i]){Tarjan_dfs(i);}
}
int ans=;
for(int i=;i<=n;i++){
if(low[i]==num[i]){ans++;}
}
for(int i=;i<=n;i++){
printf("%d %d\n",num[i],low[i]);
}
cout<<ans<<endl;
}
return ;
}
——————————————————————————————————————————————————————————————————
实在抱歉,居然搞了一个错误的模板。
由于模板的错误,之前的理解也有些偏差,其实和并查集相似的不是low,而是color。
接下来是我的板子,这是POJ2553的代码,只有solve函数与此题有关。
#include<iostream>
#include<cstdio>
#include<vector>
#include<stack>
#include<cstring>
using namespace std;
int n,m;
int book[50008];
int low[50008],num[50008],cnt=1,index;
int color[50008];
bool flag[50008];
vector<int>u[50008];
stack<int>st;
int sig=0;
void Tarjan(int t)
{
num[t]=low[t]=++index;
st.push(t);
book[t]=true;
int siz=u[t].size();
for(int i=0;i<siz;i++){
if(!num[u[t][i]]){
Tarjan(u[t][i]);
low[t]=min(low[t],low[u[t][i]]);
}
else if(book[u[t][i]]){low[t]=min(low[t],low[u[t][i]]);}
} if(num[t]==low[t]){
sig++;
while(1){ cnt=st.top();
st.pop();
color[cnt]=sig;
book[cnt]=0;
if(cnt==t){break;}
}
}
} bool init()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
u[i].clear();
}
while(!st.empty()){
st.pop();
}
memset(book,0,sizeof(book));
memset(low,0,sizeof(low));
memset(flag,0,sizeof(flag));
memset(color,0,sizeof(color));
memset(num,0,sizeof(num));
index=0;
if(n==0){return false;}
scanf("%d",&m);
int x,y;
for(int i=1;i<=m;i++){
scanf("%d%d",&x,&y);
u[x].push_back(y);
}
return true;
} void solve()
{
int siz;
int tle=0;
for(int i=1;i<=n;i++){
siz=u[i].size();
for(int j=0;j<siz;j++){
if(color[u[i][j]]!=color[i]){flag[color[i]]=true;}
}
} for(int i=1;i<=n;i++){
if(!flag[color[i]]){
tle++?printf(" %d",i):printf("%d",i);
}
}
printf("\n");
} int main()
{
while(init()){
for(int i=1;i<=n;i++){
if(!num[i]){Tarjan(i);cnt++;}
}
solve();
}
}
Tarjan 模板,高级并查集的更多相关文章
- 洛谷P3367 【模板】并查集
P3367 [模板]并查集 293通过 551提交 题目提供者HansBug 标签 难度普及- 提交 讨论 题解 最新讨论 不知道哪错了 为啥通不过最后三个节点 题解 不懂为什么MLE 最后一个数 ...
- 洛谷 P3367 【模板】并查集
P3367 [模板]并查集 题目描述 如题,现在有一个并查集,你需要完成合并和查询操作. 输入输出格式 输入格式: 第一行包含两个整数N.M,表示共有N个元素和M个操作. 接下来M行,每行包含三个整数 ...
- 并查集 P3367 【模板】并查集
P3367 [模板]并查集 #include<iostream> #include<algorithm> #include<cstdio> #include< ...
- 《程序员代码面试指南》第三章 二叉树问题 Tarjan算法与并查集解决二叉树节点间最近公共祖先的批量查询问题
题目待续.... Tarjan算法与并查集解决二叉树节点间最近公共祖先的批量查询问题 java代码
- POJ 2762 tarjan缩点+并查集+度数
Going from u to v or from v to u? Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 15494 ...
- 并查集模板题----P3367 【模板】并查集
题目描述 如题,现在有一个并查集,你需要完成合并和查询操作. 输入格式 第一行包含两个整数N.M,表示共有N个元素和M个操作. 接下来M行,每行包含三个整数Zi.Xi.Yi 当Zi=1时,将Xi与Yi ...
- 【并查集模板】并查集模板 luogu-3367
题目描述 简单的并查集模板 输入描述 第一行包含两个整数N.M,表示共有N个元素和M个操作. 接下来M行,每行包含三个整数Zi.Xi.Yi 当Zi=1时,将Xi与Yi所在的集合合并 当Zi=2时,输出 ...
- Luogu P3367 【模板】并查集
题目描述 如题,现在有一个并查集,你需要完成合并和查询操作. 输入输出格式 输入格式: 第一行包含两个整数N.M,表示共有N个元素和M个操作. 接下来M行,每行包含三个整数Zi.Xi.Yi 当Zi=1 ...
- 题解 P3367 【【模板】并查集】
#include<iostream> #include<cstdio> using namespace std; int n,m,x,y,z; ]; //f[i]表示i的祖先 ...
随机推荐
- getUserMedia API及HTML5 调用摄像头和麦克风
getUserMedia API简介 HTML5的getUserMedia API为用户提供访问硬件设备媒体(摄像头.视频.音频.地理位置等)的接口,基于该接口,开发者可以在不依赖任何浏览器插件的条件 ...
- selective search
1.引言:图像的物体识别主要有两个步骤:定位.分类.在分类的过程中,需要对图像中文物体的区域划分出来.传统的方法是利用滑窗,一个窗口一个窗口得选择,将之与目标进行比较,确定物体的位置. 为了降低搜索空 ...
- filter运行出现 <filter object at 0x000001B68F052828> 判断素数
刚接触filter时 运行总是出现<filter object at 0x000001B68F052828> 得不到想要的数据 后来发现是因为filter的结果是一个数组 需要 lis ...
- 伪GZCC官网
<html class="no-js"><head> <meta charset="utf-8"> <meta htt ...
- Jquery获取和修改img的src值的方法
转自:http://www.jb51.net/article/46861.htm 获取(代码): $("#imgId")[0].src; 修改(代码): $("#imgI ...
- HDOJ2032_杨辉三角
这是一道水题,思路很简单,把杨辉三角先求出来,然后按照输入将相应的层数的杨慧三角输出即可. HDOJ2032_杨辉三角 #include<stdio.h> #include<stdl ...
- 菜鸟教程--AJAX
一.简介1.AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术.2.AJAX = 异步 JavaScript 和 XML.3.通过在后台与服务器进行少量数据交换,AJAX 可以使网 ...
- JHipster - Generate your Spring Boot + Angular/React applications!
JHipster - Generate your Spring Boot + Angular/React applications!https://www.jhipster.tech/
- ThreadPoolExecutor使用详解
ThreadPoolExecutor机制 一.概述 1.ThreadPoolExecutor作为java.util.concurrent包对外提供基础实现,以内部线程池的形式对外提供管理任务执行,线 ...
- [转帖]浅析java程序的执行过程
浅析java程序的执行过程 转帖来源: https://www.cnblogs.com/wangjiming/p/10315983.html 之前学习过 这一块东西 但是感觉理解的不深刻. copy一 ...