SPF Tarjan算法求无向图割点(关节点)入门题
SPF
题目抽象,给出一个连通图的一些边,求关节点。以及每个关节点分出的连通分量的个数
邻接矩阵只要16ms,而邻接表却要32ms, 花费了大量的时间在加边上。
// time 16ms
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <string> 7 #include <vector> 8 #include <set> 9 #include <map> 10 #include <stack> 11 #include <queue> 12 #include <sstream> 13 #include <iomanip> 14 using namespace std; 15 typedef long long LL; 16 const int INF = 0x4fffffff; 17 const double EXP = 1e-5; 18 const int MS = 1005; 19 const int SIZE = 100005; 20 21 int edges[MS][MS]; 22 int vis[MS]; 23 int dfn[MS]; 24 int low[MS]; 25 int subnets[MS]; 26 int nodes; 27 int tdfn; 28 int sons; 29 30 void init() 31 { 32 low[1]=dfn[1]=1; 33 tdfn=1;sons=0;nodes=0; 34 memset(vis,0,sizeof(vis)); 35 vis[1]=1; 36 memset(subnets,0,sizeof(subnets)); 37 memset(edges,0,sizeof(edges)); 38 } 39 40 void DFS(int u) 41 { 42 for(int v=1;v<=nodes;v++) 43 { 44 if(edges[u][v]) 45 { 46 if(!vis[v]) 47 { 48 vis[v]=1; 49 dfn[v]=low[v]=++tdfn; // 初始化 50 DFS(v); // low[v]的值已经求出 51 low[u]=min(low[u],low[v]); 52 if(low[v]>=dfn[u]) 53 { 54 if(u!=1) 55 subnets[u]++; 56 else 57 sons++; 58 } 59 } 60 else // v已经访问过了,v是u的祖先节点,(v,u)是一条回边 61 low[u]=min(low[u],dfn[v]); 62 } 63 } 64 } 65 66 int main() 67 { 68 int u,v,find,number=1; 69 while(1) 70 { 71 scanf("%d",&u); 72 if(!u) 73 break; 74 init(); 75 scanf("%d",&v); 76 if(u>nodes) 77 nodes=u; 78 if(v>nodes) 79 nodes=v; 80 edges[u][v]=edges[v][u]=1; 81 while(1) 82 { 83 scanf("%d",&u); 84 if(!u) 85 break; 86 scanf("%d",&v); 87 if(u>nodes) 88 nodes=u; 89 if(v>nodes) 90 nodes=v; 91 edges[u][v]=edges[v][u]=1; 92 } 93 if(number>1) 94 printf("\n"); 95 printf("Network #%d\n",number++); 96 DFS(1); 97 if(sons>1) 98 subnets[1]=sons-1; 99 find=0; 100 for(int i=1;i<=nodes;i++) 101 { 102 if(subnets[i]) 103 { 104 find=1; 105 printf(" SPF node %d leaves %d subnets\n",i,subnets[i]+1); 106 } 107 } 108 if(!find) 109 printf(" No SPF nodes\n"); 110 111 } 112 return 0; 113 }
邻接表 time==32ms
1 // time 32ms 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <cmath> 6 #include <algorithm> 7 #include <string> 8 #include <vector> 9 #include <set> 10 #include <map> 11 #include <stack> 12 #include <queue> 13 #include <sstream> 14 #include <iomanip> 15 using namespace std; 16 typedef long long LL; 17 const int INF = 0x4fffffff; 18 const double EXP = 1e-5; 19 const int MS = 1005; 20 const int SIZE = 100005; 21 22 //int edges[MS][MS]; 23 struct edge 24 { 25 int v,next; 26 }edges[(MS*MS)]; // 理论上是(MS*MS)<<1,超内存。但这种情况是超级极端。(MS*MS)足够 27 int head[MS]; 28 29 int vis[MS]; 30 int dfn[MS]; 31 int low[MS]; 32 int subnets[MS]; 33 int nodes; 34 int tdfn; 35 int sons; 36 int cnt; 37 38 void init() 39 { 40 low[1]=dfn[1]=1; 41 tdfn=1;sons=0; 42 nodes=0;cnt=0; 43 memset(vis,0,sizeof(vis)); 44 vis[1]=1; 45 memset(subnets,0,sizeof(subnets)); 46 memset(edges,0,sizeof(edges)); 47 memset(head,-1,sizeof(head)); 48 } 49 50 void add(int u,int v) 51 { 52 edges[cnt].v=v;edges[cnt].next=head[u];head[u]=cnt++; 53 edges[cnt].v=u;edges[cnt].next=head[v];head[v]=cnt++; 54 } 55 56 void DFS(int u) 57 { 58 for(int i=head[u];i!=-1;i=edges[i].next) 59 { 60 int v=edges[i].v; 61 if(!vis[v]) 62 { 63 vis[v]=1; 64 dfn[v]=low[v]=++tdfn; 65 DFS(v); 66 low[u]=min(low[u],low[v]); 67 if(low[v]>=dfn[u]) 68 { 69 if(u!=1) 70 subnets[u]++; 71 else 72 sons++; 73 } 74 } 75 else 76 low[u]=min(low[u],dfn[v]); 77 } 78 } 79 80 int main() 81 { 82 int u,v,find,number=1; 83 while(1) 84 { 85 scanf("%d",&u); 86 if(!u) 87 break; 88 init(); 89 scanf("%d",&v); 90 if(u>nodes) 91 nodes=u; 92 if(v>nodes) 93 nodes=v; 94 add(u,v); 95 while(1) 96 { 97 scanf("%d",&u); 98 if(!u) 99 break; 100 scanf("%d",&v); 101 if(u>nodes) 102 nodes=u; 103 if(v>nodes) 104 nodes=v; 105 add(u,v); 106 } 107 if(number>1) 108 printf("\n"); 109 printf("Network #%d\n",number++); 110 DFS(1); 111 if(sons>1) 112 subnets[1]=sons-1; 113 find=0; 114 for(int i=1;i<=nodes;i++) 115 { 116 if(subnets[i]) 117 { 118 find=1; 119 printf(" SPF node %d leaves %d subnets\n",i,subnets[i]+1); 120 } 121 } 122 if(!find) 123 printf(" No SPF nodes\n"); 124 } 125 return 0; 126 }
转载于:https://www.cnblogs.com/767355675hutaishi/p/4445519.html
SPF Tarjan算法求无向图割点(关节点)入门题相关推荐
- tarjan算法求无向图的割点和桥
tarjan算法求无向图的割点与桥 一篇tarjan算法求割点与桥的完整的解释,写的真的好认真 以下代码来自kuangbin的模板 4.5 图的割点.桥和双连通分支的基本概念 [点连通度与边连通度] ...
- C++算法篇:DFS超详细解析(2)--- tarjan算法求无向图割边
<<<上一篇 系列文章目录 ①:无向图基本概念 ②:tarjan算法求无向图割边 前言 第一次写算法,讲得肯不透彻,有误还请指教awa 文章目录 系列文章目录 一.回顾 二.tarj ...
- Tarjan算法求无向图割边割点、最近公共祖先的总结
无向图tarjan求割边割点.最近公共祖先总结 割点:删除这个点之后整个图变成不连通的两个部分的点 割点集合:在一个无向图中删除该集合中的所有点,能使原图变成互不相连的连通块的点的集合 点连通度 ...
- tarjan算法与无向图的连通性(割点,桥,双连通分量,缩点)
基本概念 给定无向连通图G = (V, E) 割点: 对于x∈V,从图中删去节点x以及所有与x关联的边之后,G分裂为两个或两个以上不相连的子图,则称x为割点 割边(桥) 若对于e∈E,从图中删去边e之 ...
- Tarjan算法求割点与割边(python3实现)
from typing import List, Tuple''' Trajan算法求无向图的桥 '''class Tarjan:# 求无向连通图的桥@staticmethoddef getCutti ...
- 0x66.图论 - Tarjan算法与无向图连通性
目录 一.无向图的割点与桥 割点 桥/割边 时间戳 搜索树 追溯值 二.割边判定法则 三.割点判定法则 1.luogu P3388 [模板]割点(割顶) 2.luogu P3469 [POI2008] ...
- 算法提高课-图论-有向图的强连通分量-AcWing 1174. 受欢迎的牛:tarjan算法求强连通分量、tarjan算法板子、强连通图
文章目录 题目解答 题目来源 题目解答 来源:acwing 分析: 强连通图:给定一张有向图.若对于图中任意两个结点x,y,既存在从x到y的路径,也存在从y到x的路径,则称该有向图是"强连通 ...
- tarjan算法求割点割边
在上一节我们已经知道tarjan算法可以求联通图,在这里我们也运用tarjan的思想求割点与割边,首先我们先来说说割点,那么什么事割点呢,先来看一张图(a),图片来自网络 在(a)图中,我们将A点以及 ...
- Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)...
转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2194090a96bbed2db1351de8.html 基本概念: 1.割点:若删掉某点后,原连通图 ...
最新文章
- 判断数组里面的下标是否等于一个字符串
- 微软表示Edge的性能更优于Chrome和Firefox
- 文件内容查找java,java库从文件内容中查找mime类型
- Kotlin教程学习-数据类型
- Qt for Python Mac下使用 fbs 打包软件
- (十八)密度聚类DBSCAN
- linux下如何关闭防火墙、查看当前的状态、开放端口
- 关于STM32没有硬件浮点单元的纯经验之谈,是否可以在stm32上用float运算?
- 程序猿加班到深夜,你经历过没?
- Realtek显示芯片方案设计 RTD2270 RTD2281 RTD2513 RTD2525 RTD2556 RTD2785 RTD2795T 2796 VGA DVI HDMI DP转LVDS
- 数据库设计遵循的原则
- Django项目 | 使用MongoDB存储图片
- HTTP协议中的一些概念
- 信安数学/网安数学——证明形如4k-1的素数有无限个
- 玩战塔英雄不显示服务器,战塔英雄开服表
- Thinkpad t450s 加装ssd 记录
- 一家之言——智慧城市“十三五”建设着眼点
- 适合短期内想快速上手数字孪生系统的人使用的数字孪生软件推荐
- 在电脑上体验了 16 款手机 App 后,我很失望
- sas9.2智能平台连接oracle数据库操作说明文档,SAS9.2 SID更新