关于图连通性的几道题(水)

POJ 2186 强连通分量缩点

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5
 6 int en[10010], col[10010], dfn[10010], low[10010], stack[10010], tot[10010], chu[10010];
 7 bool ins[10010];
 8 int n, m, esize, dtime, stop, scc;
 9 struct edge{
10     int v, n;
11 } e[50010];
12 void insert(int u, int v)
13 {
14     e[esize].v = v;
15     e[esize].n = en[u];
16     en[u] = esize ++;
17 }
18 void dfs(int x)
19 {
20     dfn[x] = low[x] = dtime ++;
21     stack[stop++] = x;
22     ins[x] = true;
23     for (int t = en[x]; t != -1; t = e[t].n){
24         int v = e[t].v;
25         if (!dfn[v]){
26             dfs(v);
27             low[x] = min(low[x], low[v]);
28         }
29         else if (ins[v]){
30             low[x] = min(low[x], dfn[v]);
31         }
32     }
33     if (dfn[x] == low[x]){
34         scc ++;
35         while(stack[--stop] != x){
36             col[stack[stop]] = scc;
37             ins[stack[stop]] = false;
38         }
39         col[x] = scc;
40         ins[x] = false;
41     }
42 }
43 int main()
44 {
45     scanf("%d %d", &n, &m);
46     int a, b;
47     esize = 0;
48     memset(en, -1, sizeof(en));
49     for (int i = 0; i < m; i++){
50         scanf("%d %d", &a, &b);
51         insert(a, b);
52     }
53     memset(dfn, 0, sizeof(dfn));
54     memset(col, 0, sizeof(col));
55     memset(ins, 0, sizeof(ins));
56     dtime = 1; stop = 0; scc = 0;
57     for (int i = 1; i <= n; i++)
58         if (!dfn[i]) dfs(i);
59     memset(chu, 0, sizeof(chu));
60     memset(tot, 0, sizeof(tot));
61     for (int i = 1; i <= n; i++){
62         int u = col[i];
63         tot[u]++;
64         for (int t = en[i]; t != -1; t = e[t].n){
65             int v = col[e[t].v];
66             if (u != v)
67                 chu[u] ++;
68         }
69     }
70     int cnt = 0, ans;
71     for (int i = 1; i <= scc; i++)
72         if (chu[i] == 0){
73             cnt ++;
74             ans = tot[i];
75         }
76     if (cnt > 1) ans = 0;
77     printf("%d\n", ans);
78     return 0;
79 }

POJ 1144 TOJ 1026 求割点数量

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 using namespace std;
 7
 8 int esize, n, root, dtime;
 9 struct edge{
10     int v, n;
11 } e[100000];
12 int en[200], dfn[200], low[200];
13 bool cut[200];
14 int min(int a, int b)
15 {
16     if (a < b) return a; else return b;
17 }
18 void insert(int u, int v)
19 {
20     e[esize].v = v;
21     e[esize].n = en[u];
22     en[u] = esize++;
23 }
24 void dfs(int x, int fa)
25 {
26     int son = 0;
27     dfn[x] = low[x] = dtime++;
28     for (int t = en[x]; t != -1; t = e[t].n){
29         int v = e[t].v;
30         if (v == fa) continue;
31         if (!dfn[v]){
32             son++;
33             dfs(v, x);
34             low[x] = min(low[x], low[v]);
35             if ((x != root && low[v] >= dfn[x]) || (x == root && son > 1))
36                 cut[x] = true;
37         }
38         else{
39             low[x] = min(low[x], dfn[v]);
40         }
41     }
42 }
43 int main()
44 {
45     while(scanf("%d", &n) == 1 && n)
46     {
47         memset(en, -1, sizeof(en));
48         int x, y, esize = 0;
49         char ch;
50         while(scanf("%d", &x) == 1 && x){
51             while((ch = getchar()) != ‘\n‘){
52                 scanf("%d", &y);
53                 insert(x, y);
54                 insert(y, x);
55             }
56         }
57         memset(dfn, 0, sizeof(dfn));
58         memset(cut, 0, sizeof(cut));
59         root = 1; dtime = 1;
60         dfs(1, 0);
61         int ans = 0;
62         for (int i = 1; i <= n; i++)
63             if (cut[i]) {
64                 ans++;
65             }
66         printf("%d\n", ans);
67     }
68     return 0;
69 }

HDOJ 4738 无向图求桥

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5
 6 const int inf = 2147483647;
 7 int esize, n, m, dtime, ans;
 8 int low[1010], dfn[1010], en[1010], f[1010];
 9 struct edge{
10     int v, n, w;
11     bool u;
12 } e[2002000];
13 int getf(int x)
14 {
15     if (x == f[x]) return x;
16     f[x] = getf(f[x]);
17     return f[x];
18 }
19 void unionxy(int x, int y)
20 {
21     int xroot = getf(x),
22         yroot = getf(y);
23     f[xroot] = yroot;
24 }
25 void insert(int u, int v, int w){
26     e[esize].v = v;
27     e[esize].n = en[u];
28     e[esize].w = w;
29     e[esize].u = false;
30     en[u] = esize ++;
31 }
32 void dfs(int u)
33 {
34     low[u] = dfn[u] = dtime ++;
35     for (int t = en[u]; t != -1; t = e[t].n){
36         if (e[t^1].u) continue;
37         e[t].u = true;
38         int v = e[t].v;
39         if (!dfn[v]){
40             dfs(v);
41             low[u] = min(low[u], low[v]);
42             if (low[v] > dfn[u]){
43                 if (e[t].w == 0)
44                     ans = min(ans, 1);
45                 else
46                     ans = min(ans, e[t].w);
47             }
48         }
49         else
50             low[u] = min(low[u], dfn[v]);
51     }
52 }
53 int main()
54 {
55     while(scanf("%d %d", &n, &m) && (n + m))
56     {
57         memset(en, -1, sizeof(en));
58         esize = 0;
59         for (int i = 1; i <= n; i++)
60             f[i] = i;
61         int x, y, w;
62         for (int i = 0; i < m; i++){
63             scanf("%d %d %d", &x, &y, &w);
64             insert(x, y, w);
65             insert(y, x, w);
66             unionxy(x, y);
67         }
68         int cnt = 0;
69         for (int i = 1; i <= n; i++)
70             if (f[i] == i) cnt ++;
71         if (cnt > 1){
72             puts("0");
73             continue;
74         }
75         memset(dfn, 0, sizeof(dfn));
76         dtime = 1, ans = inf;
77         for (int i = 1; i <= n; i++)
78             if (!dfn[i]) dfs(i);
79         if (ans == inf) ans = -1;
80         printf("%d\n", ans);
81     }
82     return 0;
83 }

关于图连通性的几道题(水),布布扣,bubuko.com

时间: 2024-11-29 00:34:57

关于图连通性的几道题(水)的相关文章

图-&gt;连通性-&gt;无向图的连通分量和生成树

文字描述 对无向图进行遍历时,对于连通图,仅需从图中任一顶点出发,进行深度优先搜索或广度优先搜索,便可访问到图中所有顶点.但对非连通图,则需从多个顶点出发搜索,每一次从一个新的起始点出发进行搜索过程得到的顶点访问序列恰为其各个连通分量中的顶点集. 对于非连通图,每个连通分量中的顶点集,和遍历时走过的边一起构成若干棵生成树,这些连通分量的生成树组成非连通图的生成森林. 示意图 算法分析 求无向图的连通分量的生成森林的算法时间复杂度和遍历相同. 代码实现 1 //1.建立无向图 2 //2.建立无向

算法学习——动态图连通性(线段树分治+按秩合并并查集)

在考场上遇到了这个的板子题,,,所以来学习了一下线段树分治 + 带撤销的并查集. 题目大意是这样的:有m个时刻,每个时刻有一个加边or撤销一条边的操作,保证操作合法,没有重边自环,每次操作后输出当前图下所有联通块大小的乘积. 首先观察到如果没有撤销操作,那么直接用并查集就可以维护,每次合并的时候乘上要合并的两个并查集大小的逆元,然后乘上合并之后的大小即可. 那么来考虑撤销,观察到如果并查集不带路径压缩,应该是可以处理撤销操作的. 但我们并不能直接做,因为并查集的撤销必须按顺序来,就相当于每次合并

图-&gt;连通性-&gt;有向图的强连通分量

文字描述 有向图强连通分量的定义:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.有向图的极大强连通子图,称为强连通分量(strongly connected components). 用深度优先搜索求有向图的强连通分量的方法如下并假设有向图的存储结构为十字链表. 1 在有向图G上,从某个定点出发沿以该顶点为尾的弧

图-&gt;连通性-&gt;最小生成树(普里姆算法)

文字描述 用连通网来表示n个城市及n个城市间可能设置的通信线路,其中网的顶点表示城市,边表示两城市之间的线路,赋于边的权值表示相应的代价.对于n个定点的连通网可以建立许多不同的生成树,每一棵生成树都可以是一个通信网.现在,我们要选择这样一个生成树,使总的耗费最少.这个问题就是构造连通网的最小代价生成树(Minimum Cost Spanning Tree: 最小生成树)的问题.一棵生成树的代价就是树上各边的代价之和. 有多种算法可以构造最小生成树,其他多数都利用的最小生成的MST(minimum

BZOJ 1018 线段树维护图连通性

用8个bool维护即可分别为LURU,LURD,LDRU,LDRD,LULD,RURD,Side[1],Side[2]即可. Side表示这一块有没有接到右边.Merge一下就可以了.码农题,WA了一次,发现未初始化,就AC了.. 1 #include <cstdio> 2 inline int Min(int x,int y) {return x>y?y:x;} 3 inline void Swap(int &x,int &y) {int t=x;x=y;y=t;} 4

图的两种遍历-DFS&amp;BFS

DFS和BFS在图中的应用: 图连通性判定:路径的存在性:图中是否存在环:求图的最小生成树:求图的关键路径:求图的拓扑排序. DFS:简单的说,先一直往深处走,直到不能再深了,再从另一条路开始往深处走,直到所有路都走完: struct node { int next; //E[i].next指向图中与i同父的下一个结点 int to; //E[i].to指向图中i的子结点 }E[110]; int N; int fa[110]; //记录各点的父结点 bool vis[110]; //记录这个点

混合图欧拉回路(hdoj3472 HS BDC)

欧拉回路基础知识戳这里 混合图:就是图里面有的边是有向边,有的边是无向边,组成的图叫做混合图. 要判混合图是否满足欧拉回路,首先必须满足欧拉图的条件 1:欧拉回路要求所有点的度数必须都为偶数,欧拉道路要求所有点的度数两个奇数. 2:给无向的边定向,首先任意定向,这些便之间网络流建边from到to容量为1,然后对于当前入度大于出度的点y,说明有d = (入度-出度)/2的边需要变成相反方向,我们这里不进行变向,而是用一个网络流的超级汇点T,给其建边y到T,容量为d. 然后对于当前出度大于入度的点x

图(总结篇)-待完善

图->定义 图->存储结构->数组表示法 图->存储结构->邻接表 图->存储结构->十字链表 图->存储结构->邻接多重表 图->遍历->深度优先搜索 图->遍历->广度优先搜索 图->连通性 图->有向无环图及其应用->拓扑排序 图->有向无环图及其应用->关键路径 图->最短路径->单源最短路径 图->最短路径->多源最短路径 原文地址:https://www.cnbl

平衡阀工作原理(图)

平衡阀(Balance Valve)在管道或容器的各个部分存在较大的压力差或流量差,为减小或平衡该差值,在相应的管道或容器之间安设平衡阀,用以调节两侧压力的相对平衡,或通过分流的方法达到流量的平衡,是一种特殊功能的阀门.平衡阀工作原理(图) 平衡阀是在水力工况下,起到动态.静态平衡调节的阀门.平衡阀可分为三种类型:静态平衡阀.动态平衡阀及压差无关型平衡阀.静态平衡 阀亦称平衡阀.手动平衡阀.数字锁定平衡阀.双位调节阀等,它是通过改变阀芯与阀座的间隙(开度),调整阀门的Kv(阀门流通能力)来改变流