主要借助这道比较裸的题来讲一下tarjan这种算法
tarjan是一种求解有向图强连通分量的线性时间的算法。(用dfs来实现)
如果两个顶点可以相互通达,则称两个顶点强连通。如果有向图G的每两个顶点都强连通,称G是一个强连通图。有向图的极大强连通子图,称为强连通分量。
在上面这张有向图中1,2,3,4形成了一个强连通分量,而1,2,4,和1,3,4并不是(因为它们并不是极大强连通子图)。
tarjan是用dfs来实现的(用了tarjan后我们就可以对图进行缩点(当然这道裸题用不到))
这道题只要找到最大的强连通分量,并且把将该强连通分量的序号从小到大输出(如果有一样大的强连通分量,那么输出含有更小的点的那一个)
下面来道题:(tarjan代码加注释往下拉)
题目
题目描述 Description
在幻想乡,上白泽慧音是以知识渊博闻名的老师。春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄。因此慧音决定换一个能够聚集最多人数的村庄作为新的教学地点。人间之里由N个村庄(编号为1..N)和M条道路组成,道路分为两种一种为单向通行的,一种为双向通行的,分别用1和2来标记。如果存在由村庄A到达村庄B的通路,那么我们认为可以从村庄A到达村庄B,记为(A,B)。当(A,B)和(B,A)同时满足时,我们认为A,B是绝对连通的,记为<A,B>。绝对连通区域是指一个村庄的集合,在这个集合中任意两个村庄X,Y都满足<X,Y>。现在你的任务是,找出最大的绝对连通区域,并将这个绝对连通区域的村庄按编号依次输出。若存在两个最大的,输出字典序最小的,比如当存在1,,4和2,,6这两个最大连通区域时,输出的是1,,。 输入描述 Input Description
第1行:两个正整数N,M 第2..M+1行:每行三个正整数a,b,t, t = 1表示存在从村庄a到b的单向道路,t = 2表示村庄a,b之间存在双向通行的道路。保证每条道路只出现一次。 输出描述 Output Description
第1行: 1个整数,表示最大的绝对连通区域包含的村庄个数。 第2行:若干个整数,依次输出最大的绝对连通区域所包含的村庄编号。 样例输入 Sample Input 样例输出 Sample Output 数据范围及提示 Data Size & Hint
对于60%的数据:N <= 200且M <= , 对于100%的数据:N <= ,000且M <= ,
很明显这道题需要用到tarjan
#include<stdio.h>
#include<algorithm>
using namespace std;
int dfn[], low[], stack[], j, number, n, m, x, y, w, hh[], cnt, top, c, q, ans, yy[];
int color[], u, num, p[];
bool d[];
struct node
{
int next, z, e;
} b[];
void add(int aa, int bb)//邻接表
{
b[++cnt].e = bb;
b[cnt].next = hh[aa];
hh[aa] = cnt;
}
tarjan代码:
int tarjan(int k)
{
int i;
dfn[k] = low[k] = ++number;//dfn记录的是访问此节点的真实时间,low记录的是
stack[++top] = k;将当前点入栈
d[k] = true;//这是表示点k的状态
for(i = hh[k]; i != ; i = b[i].next)
{
if(!dfn[b[i].e])如果当前节点没有访问过就继续搜
{
tarjan(b[i].e);
low[k] = min(low[k], low[b[i].e]);
}
else if(d[b[i].e] == true)
{
low[k] = min(low[k], dfn[b[i].e]);
//当然也可以写成low[k]=min(low[k],low[b[i].e]);
}
}
if(dfn[k] == low[k])//如果该点是强连通分量的根,也就是说我们已经找到了一个强连通分量,就开始弹栈
{
color[k] = ++num;//把该强连通分量上的点全部染成同一种颜色
while()
{
p[num]++;//记录该强连通分量上的点
d[stack[top]] = false;//栈顶元素出栈
color[stack[top--]] = num;将栈顶元素的颜色染成当前该强连通分量的颜色
if(stack[top + ] == k)break;//因为根肯定是当前强连通分量上最先访问,也就是最先入站的,所以弹出了根代表该强连通分量上的已全部弹出
}
}
return ;
}
int main()
{
int i;
scanf("%d %d", &n, &m);
u = ;
for(i = ; i <= m; i++)
{
scanf("%d %d %d", &x, &y, &w);
if(w == )add(x, y);//建边
else
{
add(x, y);
add(y, x);
}
}
for(j = ; j <= n; j++)
{
if(!dfn[j])tarjan(j);//如果当前点没有被搜过,就从当前点进行深搜
}
for(i = ; i <= n; i++)
{
if(p[color[i]] > ans)ans = p[color[i]], u = i;
}
printf("%d\n", ans);
for(i = ; i <= n; i++)
{
if(color[i] == color[u])printf("%d ", i);
}
return ;
}
tarjan讲解(用codevs1332(tarjan的裸题)讲解)的更多相关文章
-
HDU 1248 寒冰王座(完全背包裸题)
寒冰王座 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
-
解题报告:hdu1257 LIS裸题
2017-09-02 17:28:44 writer:pprp 那个裸题练练手,讲解在之前的博客中提到了 代码如下: /* @theme:hdu1257 @writer:pprp @begin:17: ...
-
【填坑】bzoj3224 splay裸题
人生第一道splay不出所料是一道裸题,一道水题,一道2k代码都不到的题 #include <cstdio> ,n,p,q; ],c[][],size[],sp[]; void rot(i ...
-
LCT裸题泛做
①洞穴勘测 bzoj2049 题意:由若干个操作,每次加入/删除两点间的一条边,询问某两点是否连通.保证任意时刻图都是一个森林.(两点之间至多只有一条路径) 这就是个link+cut+find roo ...
-
贴一下WC总结里提到的那道裸题吧。。。
[bzoj4034][HAOI2015]T2 试题描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 ...
-
HDU 1102 最小生成树裸题,kruskal,prim
1.HDU 1102 Constructing Roads 最小生成树 2.总结: 题意:修路,裸题 (1)kruskal //kruskal #include<iostream> ...
-
hdu Flow Problem (最大流 裸题)
最大流裸题,贴下模版 view code#include <iostream> #include <cstdio> #include <cstring> #incl ...
-
POJ 3468 线段树裸题
这些天一直在看线段树,因为临近期末,所以看得断断续续,弄得有些知识点没能理解得很透切,但我也知道不能钻牛角尖,所以配合着刷题来加深理解. 然后,这是线段树裸题,而且是最简单的区间增加与查询,我参考了A ...
-
POJ 2195 Going Home 最小费用流 裸题
给出一个n*m的图,其中m是人,H是房子,.是空地,满足人的个数等于房子数. 现在让每个人都选择一个房子住,每个人只能住一间,每一间只能住一个人. 每个人可以向4个方向移动,每移动一步需要1$,问所有 ...
随机推荐
-
0010《SQL必知必会》笔记06-表的修改与删除
1.表的修改: 1.1 删除列:ALTER TABLE 表名 DROP COLUMN 列名 1.2 添加列:ALTER TABLE 表名 ADD(列名 数据类型) 1.3 修改列名:ALTER TAB ...
-
插入三层treeview代码
#region treetView加载 private void treeViewLoad() { DataView dv = navds.tbSiteKind.AsDataView(); treeV ...
-
浅谈用java解析xml文档(一)
关于xml本身的语法及使用的环境不多说了,网上有很多规则, 然对xml文档进行解析,一般分为四种解析方式,基于java官方文档的Dom 和Sax解析,还有就是基于 第三方jar包的 Jdom 和 Do ...
-
soso街景开发——在移动应用(网站)中的应用
腾讯soso街景为用户提供JavaScript API1.0和JavaScript API2.0,可供用户在网站中应用soso街景地图. 街景可以应用于各个方面,如果你需要开发的网站是一款涉及都旅游, ...
-
Android学习之Image操作及时间日期选择器
一.基础学习 1.ImageView是图片容器,就相当于RadioGroup是RadioButton的容器一样,是View的直接子类. 1: <ImageView 2: android:id=& ...
-
[C++空间分配]new运算符、operator new、placement new的区别于联系
先科普一下: 1. new的执行过程: (1)通过operator new申请内存 (2)使用placement new调用构造函数(内置类型忽略此步) (3)返回内存指针 2. new和malloc ...
-
springMVC+angular+bootstrap+mysql的简易购物网站搭建
springMVC+angular+bootstrap+mysql的简易购物网站搭建 介绍 前端的css框架用了bootstrap, 以及bootstrap的JS组件, 以及很好用的angular(a ...
-
MySQL数据库面试
1. MySql的存储引擎的不同 特点 Myisam BDB Memory InnoDB Archive 存储限制 没有 没有 有 64TB 没有 事务安全 支持 支持 锁机制 表锁 页锁 ...
-
C# for Python(Nugut Iron包)
cInronPython是一种在.NET和Mono上实现的Python语言,使用InronPython就可以在.NET环境中调用Python代码 安装InronPython Python: port ...
-
【Java基础】11、java方法中只有值传递,没有引用传递
public class Example { String testString = new String("good"); char[] testCharArray = {'a' ...