- 后续进行补充详细文章
Tarjan算法 求无向图的桥和割点
#include <iostream>
#include <cstring>
using namespace std;
typedef struct{
int to;
int next;
}node;
int head[110];
node edge[110<<1];
int dfn[110];
int low[110];
int n,m,cnt,cnts,root;
int a,b;
void tarjan_e(int u){
/* 找桥 */
dfn[u] = low[u] = cnts++;
for (int i = head[u]; i!=-1; i = edge[i].next)
{
int v = edge[i].to;
if(!dfn[v]){
tarjan_e(v);
low[u] = min(low[u],low[v]);
if(low[u] < low[v]){
cout << u << "---" << v << endl;
}
}else{
low[u] = min(low[u],low[v]); // 最后一个节点碰到头
}
}
}
void tarjan_v(int u){
// 寻找割点
if(dfn[u]) return;
int count = 0;
dfn[u] = low[u] = cnts++;
for (int i = head[u]; i!=-1;i= edge[i].next){
int v = edge[i].to;
if(!dfn[v]){
tarjan_v(v);
low[u] = min(low[u],low[v]);
if(low[v] >= dfn[u]){
count++;
if(u!=root || count > 1){
cout << u << "is 割点" << endl;
}
}
}else{
low[u] = min(low[u],low[v]);
}
}
}
void add(int s,int e){
edge[cnt].to = e;
edge[cnt].next = head[s];
head[s] = cnt++;
}
void init_time_back(){
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
cnts = 1;
}
int main(){
cnt = 0;
cnts = 1;
memset(head,-1,sizeof(head));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
cout << "请输入有多少个节点:";
cin >> n;
cout << "请输入有多少条边:";
cin >> m;
for (int i = 0; i < m; i++)
{
cout << "输入格式 (起始节点 目标节点):";
cin >> a >> b;
add(a,b);
}
//针对于单个图
tarjan_e(1);
init_time_back();
cout << "请输入根节点:";
cin >> root;
tarjan_v(1);
}