您的位置:首页 > 其它

tarjan算法

2016-04-13 21:21 106 查看
以下内容为个人理解,有错误地方还请指出。

须知概念:

Dfs搜索树,回边,交叉边(无向图的dfs树不存在交叉边);

dfn[u] :u的dfs序

low[u] :从u或u的子孙出发,通过回边可以到达的最小的dfs序

对于Tarjan算法中,我们得到了dfn和low两个数组,

low[u]:=min(low[u],dfn[v])——(u,v)为回边,v不是u的子树;

low[u]:=min(low[u],low[v])——(u,v)为树枝边,v为u的子树;

下边对其进行讨论:

若low[v]>=dfn[u],则u为割点,u和它的子孙形成一个块。因为这说明u的子孙不能够通过其他边到达u的祖先,这样去掉u之后,图必然分裂为两个子图。

若low[v]>dfn[u],则(u,v)为割边。理由类似于上一种情况。

该算法要求图中不能有重边;

Tarjan 算法的任务就是算出每个点的low值,然后根据图的性质去使用low值。

可以用tarjan算法求解缩点,割点,割边,点双连通分量,边双联通分量,强连通分量等。



例题可参考

/article/8996906.html
http://blog.csdn.net/u013569304/article/details/51146686


//代码实现
vector<int>head[maxn];//邻接表
tarjan_dfs(int rt,int father)//father为rt的父节点
{
int son=0;//rt的子女数
dfn[rt]=low[rt]=dep_tmp++;
vis[rt]=true;
for(int i=0,len=head[rt].size();i<len;++i)
{
int v=head[rt][i];
if(!vis[v])
{
son++;
tarjan_dfs(v,rt);
low[rt]=min(low[rt],low[v]);
}
else if(v!=father)//不要原路返回
{
low[rt]=min(low[rt],dfn[v]);
}
if(  (rt!=root && low[v]>=dfn[rt] )|| (rt==root && son>1) )
{
cut[rt]=true;//标记割点
}
if( low[v]>dfn[rt]
{
cut_edge[rt][v]=true;//标记割边
cut_edge[v][rt]=true;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: