重连通分量的求解
提两点:
1.对于每个点连通分量,都是根据割点来找的。
2.边入栈, 到当前边等于栈顶时停止出栈。
3.割点属于多个点连通分量。
邻接矩阵:
View Code
#include<stdio.h> #include<string.h> #define maxn 22 #define maxm 444 #define inf 1000000000 int min(int a, int b) { return a < b ? a : b; } int n, m; bool map[maxn][maxn]; struct EE { int u, v; void print() { printf("%d-%d", u, v); } bool cmp(EE &t) { return (t.u == u && t.v == v) || (t.u == v && t.v == u); } }e[maxm]; int top; int dfn[maxn]; int low[maxn]; int id; void dfs(int u) { int i, v; EE t, tt; dfn[u] = low[u] = ++id; for(v = 1; v <= n; v++) { if(map[u][v]) { t.u = u; t.v = v; e[++top] = t; map[v][u] = 0;// 避免边重复入栈。也排除了不回走的情况 //当走过<u,v>后,不需要再走<v,u>,不走<v,u>不影响对割点的求解 if(!dfn[v]) { dfs(v); low[u] = min(low[u], low[v]); if(low[v] >= dfn[u]) // 割点的条件 { //可以打印,也可以保存 bool flag = 1; while(1) { if(top == -1) break; if(flag) flag = 0; else printf(" "); tt = e[top--]; tt.print(); if(tt.cmp(t)) break; } printf("\n"); } } else low[u] = min(low[u], dfn[v]); } } } void init() { memset(dfn, 0, sizeof(dfn)); memset(map, 0, sizeof(map)); top = -1; id = 0; } int main() { int i, j; int x, y; while( ~scanf("%d%d", &n, &m)) { init(); while(m--) { scanf("%d%d", &x, &y); map[x][y] = map[y][x] = 1; } dfs(1); } return 0; } /* 7 9 1 2 1 3 1 6 1 7 2 3 2 4 2 5 4 5 6 7 */
邻接表:
View Code
#include<stdio.h> #include<string.h> #define maxn 22 #define maxm 444 #define inf 1000000000 int min(int a, int b) { return a < b ? a : b; } struct E { int v, next, vis; }edge[maxm]; int head[maxn], tot; int n, m; void add(int s, int t) { edge[tot].v = t; edge[tot].vis = 1; edge[tot].next = head[s]; head[s] = tot++; edge[tot].v = s; edge[tot].vis = 1; edge[tot].next = head[t]; head[t] = tot++; } struct EE { int u, v; void print() { printf("%d-%d", u, v); } bool cmp(EE &t) { return (t.u == u && t.v == v) || (t.u == v && t.v == u); } }e[maxm]; int top; int dfn[maxn]; int low[maxn]; int id; void dfs(int u, int fa) { int i, v; EE t, tt; dfn[u] = low[u] = ++id; for(i = head[u]; i != -1; i = edge[i].next) { v = edge[i].v; if(edge[i].vis) { t.u = u; t.v = v; e[++top] = t; edge[i].vis = edge[i^1].vis = 0;// 避免边重复入栈。 if(!dfn[v]) { dfs(v, u); low[u] = min(low[u], low[v]); if(low[v] >= dfn[u]) { bool flag = 1; while(1) { if(top == -1) break; if(flag) flag = 0; else printf(" "); tt = e[top--]; tt.print(); if(tt.cmp(t)) break; } printf("\n"); } } else low[u] = min(low[u], dfn[v]); } } } void init() { memset(dfn, 0, sizeof(dfn)); memset(head, -1, sizeof(head)); top = -1; tot = 0; id = 0; } int main() { int i, j; int x, y; while( ~scanf("%d%d", &n, &m)) { init(); while(m--) { scanf("%d%d", &x, &y); add(x, y); } dfs(1, -1); } return 0; }


浙公网安备 33010602011771号