标签:
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1014 Accepted Submission(s): 206
给你一个无向图,有多次操作。每次操作加入一条边,然后询问有多少桥。
就先Tarjan求出有多少桥,然后每次操作,就在搜索树上求个lca,在求的过程中遇到的桥都会失效,因为构成了环。详见代码
#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<vector> #include<cstring> #include<string> #include<algorithm> #include<stack> #define MAX_N 100005 using namespace std; vector<int> G[MAX_N]; int father[MAX_N]; int dfn[MAX_N],low[MAX_N],ind=0; bool vis[MAX_N]; int n,m; int sum = 0; bool isBridge[MAX_N]; int p; void Tarjan(int u) { father[u] = p; dfn[u] = low[u] = ++ind; vis[u] = 1; for (int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if (v == p)continue; if (!vis[v]) { int tmp = p; p = u; Tarjan(v); p = tmp; low[u] = min(low[u], low[v]); if (low[v] > dfn[u]) { sum++; isBridge[v] = 1; } } else low[u] = min(dfn[v], low[u]); } } int main() { int cas = 0; cin.sync_with_stdio(false); while (cin >> n >> m) { if (n == 0 && m == 0)break; memset(vis, 0, sizeof(vis)); for (int i = 0; i <= n; i++)G[i].clear(); sum = 0; memset(isBridge, 0, sizeof(isBridge)); ind = 0; memset(father, 0, sizeof(father)); for (int i = 0; i < m; i++) { int u, v; cin >> u >> v; G[u].push_back(v); G[v].push_back(u); } p = 0; Tarjan(1); int q; cin >> q; cout << "Case " << ++cas << ":" << endl; while (q--) { int u, v; cin >> u >> v; if (dfn[u] < dfn[v])swap(u, v); while (dfn[u] > dfn[v]) { if (isBridge[u])sum--; isBridge[u] = 0; u = father[u]; } while (u != v) { if (isBridge[v])sum--; isBridge[v] = 0; v = father[v]; } cout << sum << endl; } cout << endl; } return 0; }
注意要扩栈
标签:
原文地址:http://www.cnblogs.com/HarryGuo2012/p/4716340.html