关键路径
/* 程序:求关节点(无向图) * 分析: * 一个low数组,low[u] = min(low[v] | v in n) * 若low[v] >= low[u],则u是关节点 * 步骤: * 1.初始状态:一个无向图 * 1,数据结构:vector<int>邻接表,vis数组,low数组,count序号全局变量 * 2,初始化: * 2.过程: * 1,判断根节点是否是关节点 1,若生成树的根节点有两可或两颗以上的子树,则此根节点必为关节点 * 2,深度优先搜索遍历邻接表,更新序号数组 * 3,后序遍历 * 4,判断:若low[v] >= low[u],则u是关节点,输出,否则更新low[u]值 */ #include <iostream> #include <vector> #include <algorithm> #include <cstring> using namespace std; #define MAX 1001 vector<int> g[MAX]; int vis[MAX]; int low[MAX]; int cnt; int ans; bool judge(int u, int v, int a, int b) { if (a == u || b == u) return false; if (!vis[a] && !vis[b]) return false; else if (vis[a] && !vis[b]) if (vis[a] > vis[u]) return true; else if (!vis[a] && vis[b]) if (vis[b] > vis[u]) return true; else { if (vis[a] < vis[u] && vis[b] > vis[u]) return true; else if (vis[a] > vis[u] && vis[b] < vis[u]) return true; else return false; } } void dfs(int u, int fa, int a, int b) { vis[u] = ++cnt; int _min = vis[u]; vector<int>::iterator it; for (it = g[u].begin(); it < g[u].end(); it++) { int v = *it; if (!vis[v]) { // 后序遍历 dfs(v, u, a, b); // 判断关节点 if (low[v] >= vis[u]) { // 写成了low[v] >= low[u],明显错误,此时low[u]还没求出来呢 if (judge(u, v, a, b) == true) { ans++; } } // 更新_min _min = min(_min, low[v]); } else { if (v != fa) _min = min(_min, vis[v]); // 写成了_min = min(_min, vis[v]);注意细节区别 } } low[u] = _min; } void CriticalNode(int root, int n, int a, int b) { // 初始化 memset(vis, 0, sizeof(vis)); memset(low, 0, sizeof(low)); cnt = 0; ans = 0; // 先遍历根节点第一个孩子节点 vector<int>::iterator it = g[root].begin(); vis[root] = ++cnt; dfs(*it, root, a, b); // 判断根节点是否为关节点并遍历其余孩子节点 if (cnt < n) { // cout << root << endl; if (a == root || b == root) ; else if (!vis[a] && vis[b]) ans++; else if (vis[a] && !vis[b]) ans++; for (++it; it < g[root].end(); it++) { if (!vis[*it]) dfs(*it, root, a, b); } } } void AddEdge(int u, int v) { g[u].push_back(v); g[v].push_back(u); } int main() { int n, m, u, v, a, b; while (cin >> n >> m) { for (int i = 0; i < n; i++) g[i].clear(); for (int i = 0; i < m; i++) { cin >> u >> v; AddEdge(u - 1, v - 1); } cin >> a >> b; --a; --b; // 细节,忘了做减一,前面记着了,后面的忘了,还是提醒和熟练得不够! CriticalNode(0, n, a, b); // cout << cnt << endl; if (a == b || cnt < n) cout << -1 << endl; else cout << ans << endl; } return 0; }