图论---求割点,求桥(tarjan) (模板)
来源:互联网 发布:wampserver mac 编辑:程序博客网 时间:2024/05/29 00:31
无向图求桥和求割点用的是同一个做法。
具体的原理可以看大白书和 @泳裤王子,无向连通图的割点、桥
下面是代码:
//现在发现这么写不能排除重边,需要特判一下!桥如果有重边就不是桥了
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <stack> #include <bitset> #include <queue> #include <set> #include <map> #include <string> #include <algorithm> using namespace std;#define clr(a,b) memset(a,b,sizeof(a))#define pb(a) push_back(a)#define fir first#define se second#define LL long longtypedef pair<int,int> pii;typedef pair<LL,int> pli;typedef pair<LL,LL> pll;const int maxn = 1e6+5;const LL inf = 0x3f3f3f3f3f3f3f3f;LL mod = 1e9+7;double eps = 0.00000001;double PI = acos(-1);vector<int> g[1005];int n,low[1005],dfn[1005],dfs_clock,iscut[1005];vector<pii> ans;//dfn[i]为点i在dfs遍历中的次序//low[i]为点i能通过非树边回到的遍历序号最小的点//dfs_clock用来计数,iscut用来表示是否是割点。//ans用pair来存桥void init() { //初始化 for(int i = 0;i <= n;i++) g[i].clear(); ans.clear(); dfs_clock = 0; clr(dfn,0); clr(iscut,0); clr(low,0);}int dfs(int u,int fa) { //dfs求每个点的dfn和low low[u] = dfn[u] = ++dfs_clock; int child = 0; for(int i = 0;i < g[u].size();i++) { int v = g[u][i]; if(!dfn[v]) { child++; low[v] = dfs(v,u); low[u] = min(low[u],low[v]); if(low[v] >= dfn[u]) { //判断割点 iscut[u] = true; } if(low[v] > dfn[u]) { //判断桥 int a = u,b = v; if(a > b) swap(a,b); ans.pb(make_pair(a,b)); } } else if(dfn[v] < dfn[u] && v != fa) { low[u] = min(low[u],dfn[v]); } } if(fa < 0 && child == 1) iscut[u] = false; //特判树根是不是割点 return low[u];}void input() { //输入 int u,v; for(int i = 1;i <= n;i++) { char str[50]; scanf("%d%s",&u,str); int x = 0; for(int j = 0;str[j];j++) { if(str[j] >= '0' && str[j] <= '9') x = x*10+(str[j]-'0'); } for(int i = 1;i <= x;i++) { scanf("%d",&v); g[u].pb(v); g[v].pb(u); } }}int main() { while(scanf("%d",&n) != EOF) { int u,v; init(); input(); for(int i = 1;i <= n;i++) if(!dfn[i]) dfs(i,-1); /*for(int i = 1;i <= n;i++) { for(int e : g[i]) printf("%d ",e); cout<<endl; }*/ /*int ans = 0; for(int i = 1;i <= n;i++) //输出割点 if(iscut[i]) ans++; cout<<ans<<endl;*/ printf("%d critical links\n",ans.size()); //输出桥 sort(ans.begin(),ans.end()); for(auto it : ans) cout<<it.fir<<" - "<<it.se<<endl; cout<<endl; }}/*80 1 11 3 2 0 32 2 1 33 3 1 2 44 1 37 1 66 1 75 0*/
阅读全文
0 0
- 图论---求割点,求桥(tarjan) (模板)
- UVA796Critical Links(求桥)(tarjan模板题)
- poj 2186 tarjan求强连通分量(模板题)
- POJ1330 Nearest Common Ancestors (tarjan离线求LCA模板)
- hdu1269迷宫城堡(tarjan求强连通分量模板)
- tarjan缩点/求桥模板
- 求割边模板(tarjan)
- tarjan(SCC)模板
- tarjan模板(hdu1269)
- 求割点模板(tarjan算法思路)
- 最小生成树 (tarjan 求桥)
- dfs(tarjan)求lca
- HDU 1269(Tarjan模板)
- 强联通 tarjan (模板)
- Uva247(tarjan模板题)
- poj 3177&&poj 3352加边构双联通(有重边)用tarjan 模板求的
- tarjan模板(缩点,求有向图强连通分量)
- HDU 2586 How far away ? (LCA模板题 Tarjan算法求最小公共祖先)
- poj 1330_Nearest Common Ancestors_LCA
- RTEMS实现FDT support for Beaglebone
- Java泛型详解
- 编译SOEM(Simle Open EtherCAT Master)-windows篇
- 新建unittest的步骤
- 图论---求割点,求桥(tarjan) (模板)
- Linux服务器内外网端口转发映射
- Matlab绘图中的对象容器(Object Containers)
- 【Android】如何实现启动APP时引导页、欢迎页功能设置之(二)设置只在第一次启动APP时跳入引导界面
- 实现点赞和收藏效果
- Spark-2.1.0-hadooop-2.6.0-cdh5.7.0源码编译
- 设置mysql自动运行
- Android获取系统信息---获取CPU数
- 华为校招上机编程之““字符串的分割””