割点割边连通分量等连通性相关算法
2015-02-18 17:45
316 查看
FloodFill
不说了….大家都会写…..无向图割点Tarjan算法
主过程是一个DFS.我们使用DFS对每个点记录两个值:
1.dfn[i] 表示点i是第几个DFS到的点.
2.low[i] 表示从点i出发,不经过DFS的点能绕回而取得的最小的dfn值.
那么当low[i]==dfn[i]时,i的子节点就只能从一条不是DFS中路径的路径回到自己,而不能回到i的父节点.
于是我们就可以断定i是一个割点.
dfn很好理解.
但是low怎么理解呢?
显然,我们的主要目的是找环.
假设我们DFS,经过了点i,到达点j.
那么DFS路径必定是一条点i到点j的路径.
我们想要找环,就一定不能从DFS路径走,而是要从别的地方走.
low一直取min就是为了使找到的环尽量大,使得它是极大环,只有这样的环才是一个严格的连通分量.
Code
#include <cstdio> #include <iostream> #include <fstream> #include <cmath> #include <cstdlib> #include <algorithm> #include <cstring> typedef long long ll; typedef unsigned long long ull; typedef unsigned int uint; typedef double db; int getint() { int res=0; char c=getchar(); bool m=false; while(c<'0' || c>'9') m=(c=='-'),c=getchar(); while('0'<=c && c<='9') res=res*10+c-'0',c=getchar(); return m ? -res : res; } const db eps=1e-18; bool feq(db a,db b) { return fabs(b-a)<eps; } using namespace std; const int INF=(1<<30)-1; struct edge { int in; edge*nxt; }pool[200000]; edge*et=pool; edge*eds[1050]; inline edge*addedge(int i,int j) { et->in=j; et->nxt=eds[i]; eds[i]=et++; } #define FOREACH_EDGE(i,j) for(edge*i=eds[j];i;i=i->nxt) int n,m; bool used[1050]; int dfn[1050]; int low[1050]; int cnt[1050]; int f[1050]; bool ins[1050]; int cur; void DFS(int x) { used[x]=true; low[x]=dfn[x]=cur++; ins[x]=true; FOREACH_EDGE(i,x) { if(!used[i->in]) { DFS(i->in); if(low[i->in]==dfn[x]) cnt[x]++; low[x]=min(low[x],low[i->in]); }else { if(i->in!=f[x]) low[x]=min(low[x],dfn[i->in]); } } ins[x]=false; } void INIT() { et=pool; memset(eds,0,sizeof(eds)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(cnt,0,sizeof(cnt)); memset(f,0,sizeof(f)); memset(used,0,sizeof(used)); } int main() { int a,b,T=1; while(a=getint()) { b=getint(); INIT(); addedge(a,b); addedge(b,a); while(a=getint()) { b=getint(); addedge(a,b); addedge(b,a); } cur=1; f[1]=1; DFS(1); printf("Network #%d\n",T); int tot=0; if(cnt[1]>=2) printf(" SPF node %d leaves %d subnets\n",1,cnt[1]),tot++; for(int i=2;i<=1000;i++) { if(cnt[i]!=0) { printf(" SPF node %d leaves %d subnets\n",i,cnt[i]+1); tot++; } } if(!tot) printf(" No SPF nodes\n"); printf("\n"); T++; } return 0; }
未完待续
无向图割边
有向图割点
有向图割边
强连通分量Tarjan算法
双连通分量Tarhan算法
相关文章推荐
- 连通分量相关算法学习笔记
- Targan 算法[有向图强连通分量]
- 强连通分量的三种算法
- hdu 4685 Prince and Princess(匈牙利算法 连通分量)
- tarjan算法求强连通分量
- 强连通分量 算法摘记
- 强连通分量算法; 重在理解原理分析 ; 算法导论讲的很明白;
- 求有向图强连通分量:Trajan算法模板
- 强连通分量及缩点tarjan算法解析
- 强连通分量的三种算法和四种实现
- POJ2375 Cow Ski Area (添最少边构造强连通分量的某个与入度出度相关的结论)
- soj 3134: windy和水星 Stoer-Wagner算法求无向图的最小割集:一个无向连通网络,去掉一个边集可以使其变成两个连通分量则这个边集就是割集;最小割集当然就权和最小的割集
- 求强连通分量的三种算法——Kosaraju, Tarjan, Gabow
- 强连通分量的三种算法
- 求强连通分量几种算法的比较
- 求无向图的连通分量 算法
- 有向图强连通分量的Tarjan算法
- tarjan 算法模板(边连通分量)
- 强连通分量分解--Kosaraju算法分析与证明
- Targan 算法[有向图强连通分量]