POJ 3694 Network
tarjan+LCA。
先用tarjan进行缩点。
然后用dfn[u] < low[v]判断是不是桥。
讲桥标记起来并且计算出桥数。
对于每个案例的u和v
利用LCA用fath数组先找到u和v的祖先,如果在路径中出现的桥,就把桥标记成普通边并将桥数–。
然后输出对应的桥数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 5 using namespace std; 6 7 const int maxn = 100006; 8 const int maxm = 200005; 9 int n, m, tol, cnt; 10 int brinum; 11 12 struct Node { 13 int u; 14 int v; 15 int next; 16 }; 17 Node node[2 * maxm]; 18 int dfn[maxn]; 19 int low[maxn]; 20 int fath[maxn]; 21 int head[maxn]; 22 bool vis[maxn]; 23 bool bridge[maxn]; 24 25 void init() { 26 brinum = tol = cnt = 0; 27 memset(dfn, 0, sizeof(dfn)); 28 memset(low, 0, sizeof(low)); 29 memset(node, 0, sizeof(node)); 30 memset(fath, 0, sizeof(fath)); 31 memset(head, -1, sizeof(head)); 32 memset(vis, false, sizeof(vis)); 33 memset(bridge, 0, sizeof(bridge)); 34 } 35 36 void addnode(int u, int v) { 37 node[tol].u = u; 38 node[tol].v = v; 39 node[tol].next = head[u]; 40 head[u] = tol++; 41 } 42 43 void dfs(int u, int fa) { 44 dfn[u] = low[u] = ++cnt; 45 fath[u] = fa; 46 for(int i=head[u]; i != -1; i=node[i].next) { 47 int v = node[i].v; 48 if(!dfn[v]) { 49 dfs(v, u); 50 low[u] = min(low[u], low[v]); 51 } else if(v != fa) { 52 low[u] = min(low[u], dfn[v]); 53 } 54 } 55 } 56 57 void tarjan() { 58 dfs(1, 1); 59 } 60 61 void findbridge() { 62 for(int v=1; v<=n; v++) { 63 int u = fath[v]; 64 if(dfn[u] < low[v] && u != v) { 65 bridge[v] = true; 66 brinum++; 67 } 68 } 69 } 70 71 void LCA(int u, int v) { 72 while(dfn[u] > dfn[v]) { 73 if(bridge[u]) { 74 brinum--; 75 bridge[u] = false; 76 } 77 u = fath[u]; 78 } 79 while(dfn[v] > dfn[u]) { 80 if(bridge[v]) { 81 brinum--; 82 bridge[v] = false; 83 } 84 v = fath[v]; 85 } 86 while(u != v) { 87 if(bridge[u]) { 88 bridge[u] = false; 89 brinum--; 90 } 91 if(bridge[v]) { 92 bridge[v] = false; 93 brinum--; 94 } 95 u = fath[u]; 96 v = fath[v]; 97 } 98 printf("%d\n", brinum); 99 } 100 101 int main() { 102 int cas = 1; 103 while(scanf("%d%d",&n, &m), n||m) { 104 init(); 105 for(int i=1; i<=m; i++) { 106 int u, v; 107 scanf("%d%d", &u, &v); 108 addnode(u, v); 109 addnode(v, u); 110 } 111 tarjan(); 112 findbridge(); 113 int q; 114 scanf("%d", &q); 115 printf("Case %d:\n", cas++); 116 for(int i=1; i<=q; i++) { 117 int u, v; 118 scanf("%d%d", &u, &v); 119 LCA(u, v); 120 } 121 puts(""); 122 } 123 return 0; 124 }