二分图强连通分量 tarjan 模板
2016-03-14 20:36
309 查看
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<vector>
#define maxx 200000
using namespace std;
int a,b,c,d,n,m;
int cnt,fail,biao;
//cnt是每个强连通分量的编号
//fail是栈sta的指针
//biao用于给节点编号
int sta[maxx],belong[maxx],dnf[maxx],low[maxx];
//sta是栈
//belong[i]代表节点i所在的强连通分量编号
//dnf是每个节点的编号
//low其实我也不知道是啥,只要懂他的作用就ok
bool insta[maxx];//节点是否在栈中
vector<int> lin[maxx];//图
int tarjan(int i)
{
int j;
dnf[i]=low[i]=++biao;
sta[++fail]=i;
insta[i]=true;//编号并入栈
for (unsigned k=0;k<lin[i].size();k++)
{
j=lin[i][k];
if (dnf[j]==0) //如果子节点没有编号
{
tarjan(j);
low[i]=min(low[i],low[j]);//父亲节点low值是其子节点中low的最小值
}
else if (insta[j] && dnf[j]<low[i])
low[i]=dnf[j]; //好吧这句我不知道为啥,问了老师来补充
}
if (low[i]==dnf[i])//如果形成了一个环,即形成了一个强连通分量,出栈,更新belong数组
{
cnt++;
do //不会这一句的童鞋不要乱改这里,否则可能会错
{
j=sta[fail--];
belong[j]=cnt;
insta[j]=0;
}
while(i!=j);
}
}
int solve()
{
for (int i=1;i<=n;i++)//初始化
{
vis[i]=0;
insta[i]=false;
sta[i]=0;
belong[i]=0;
dnf[i]=0;
low[i]=0;
}
for (int i=1;i<=n;i++)
if (dnf[i]==0) //图可能不连通
tarjan(i);
}
int main()
{
n=6;
lin[1].push_back(3);
lin[1].push_back(2);
lin[2].push_back(4);
lin[3].push_back(5);
lin[3].push_back(4);
lin[4].push_back(1);
lin[4].push_back(6);
lin[5].push_back(6);
solve();
for(int i=1;i<=n;i++)
cout<<belong[i]<<" ";
cout<<endl;
return 0;
}
#include<string.h>
#include<stdio.h>
#include<vector>
#define maxx 200000
using namespace std;
int a,b,c,d,n,m;
int cnt,fail,biao;
//cnt是每个强连通分量的编号
//fail是栈sta的指针
//biao用于给节点编号
int sta[maxx],belong[maxx],dnf[maxx],low[maxx];
//sta是栈
//belong[i]代表节点i所在的强连通分量编号
//dnf是每个节点的编号
//low其实我也不知道是啥,只要懂他的作用就ok
bool insta[maxx];//节点是否在栈中
vector<int> lin[maxx];//图
int tarjan(int i)
{
int j;
dnf[i]=low[i]=++biao;
sta[++fail]=i;
insta[i]=true;//编号并入栈
for (unsigned k=0;k<lin[i].size();k++)
{
j=lin[i][k];
if (dnf[j]==0) //如果子节点没有编号
{
tarjan(j);
low[i]=min(low[i],low[j]);//父亲节点low值是其子节点中low的最小值
}
else if (insta[j] && dnf[j]<low[i])
low[i]=dnf[j]; //好吧这句我不知道为啥,问了老师来补充
}
if (low[i]==dnf[i])//如果形成了一个环,即形成了一个强连通分量,出栈,更新belong数组
{
cnt++;
do //不会这一句的童鞋不要乱改这里,否则可能会错
{
j=sta[fail--];
belong[j]=cnt;
insta[j]=0;
}
while(i!=j);
}
}
int solve()
{
for (int i=1;i<=n;i++)//初始化
{
vis[i]=0;
insta[i]=false;
sta[i]=0;
belong[i]=0;
dnf[i]=0;
low[i]=0;
}
for (int i=1;i<=n;i++)
if (dnf[i]==0) //图可能不连通
tarjan(i);
}
int main()
{
n=6;
lin[1].push_back(3);
lin[1].push_back(2);
lin[2].push_back(4);
lin[3].push_back(5);
lin[3].push_back(4);
lin[4].push_back(1);
lin[4].push_back(6);
lin[5].push_back(6);
solve();
for(int i=1;i<=n;i++)
cout<<belong[i]<<" ";
cout<<endl;
return 0;
}
相关文章推荐
- Swift--UINavigationController
- Hdu---1010
- SharePoint2013 IT Professional - 介绍Alternate Access Mappings
- 设计模式之概述
- ATOM特效显示
- 每周总结
- 深入分析 Java 中的中文编码问题 (文章来自网络)
- Combination Sum
- C++中 容易忽视的const 修饰符
- 构建之法--软件工程学习随笔之二
- 本地linux下安装discuz
- poj 1109 Palindrome 最长递增子序列
- leetcode 60. Permutation Sequence
- HDU1236排名
- mapreduce原理和执行过程
- MYSQL查询优化
- 几何原本查询程序1.0
- 实用的JS正则表达式(手机号码/IP正则/邮编正则/电话等)
- U3D游戏开发—程序员转型篇(三)菜单的认识
- 简单.STL