HDU 4005 the war
Question Link
Question: For a connected undirected graph, each side has a price to blow up. Now we need to build an edge (You Don't Know), and then you need the minimum price you need, make sure that no matter where the image is built, you can blow it up so that the graph is not connected.
Idea: It is necessary to blow up the bridge. Therefore, we need to first build a double-link deflation point and get a tree. The tree edge is to be blown up. Then we need to find a minimum edge and start from the two points on the edge, in the path, two points of the two paths containing the minimum value are connected to form a ring. This ring ensures the lowest cost, except for the minimum edge of this ring, is the answer. In this way, we can use a DFS to search for each subtree for maintenance.
Code:
#include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;const int N = 10005;const int M = 200005;int n, m;struct Edge {int u, v, val, id;bool iscut;Edge() {}Edge(int u, int v, int val, int id) {this->u = u;this->v = v;this->val = val;this->id = id;this->iscut = false;}} edge[M];int en, first[N], next[M];void init() {en = 0;memset(first, -1, sizeof(first));}void add_edge(int u, int v, int val, int id) {edge[en] = Edge(u, v, val, id);next[en] = first[u];first[u] = en++;}int pre[N], dfn[N], dfs_clock, bccn, bccno[N];vector<Edge> bcc[N];void dfs_cut(int u, int id) {pre[u] = dfn[u] = ++dfs_clock;for (int i = first[u]; i + 1; i = next[i]) {if (edge[i].id == id) continue;int v = edge[i].v;if (!pre[v]) {dfs_cut(v, edge[i].id);dfn[u] = min(dfn[u], dfn[v]);if (dfn[v] > pre[u])edge[i].iscut = edge[i^1].iscut = true;} else dfn[u] = min(dfn[u], pre[v]);}}void find_cut() {dfs_clock = 0;memset(pre, 0, sizeof(pre));for (int i = 1; i <= n; i++)if (!pre[i]) dfs_cut(i, -1);}void dfs_bcc(int u) {bccno[u] = bccn;for (int i = first[u]; i + 1; i = next[i]) {if (edge[i].iscut) continue;int v = edge[i].v;if (bccno[v]) continue;dfs_bcc(v);}}const int INF = 0x3f3f3f3f;Edge Mine;void find_bcc() {bccn = 0;memset(bccno, 0, sizeof(bccno));for (int i = 1; i <= n; i++) {if (!bccno[i]) {bccn++;dfs_bcc(i);}}for (int i = 1; i <= bccn; i++) bcc[i].clear();Mine.val = INF;for (int i = 0; i < en; i++) {if (!edge[i].iscut) continue;if (Mine.val > edge[i].val)Mine = edge[i];int u = bccno[edge[i].u], v = bccno[edge[i].v], w = edge[i].val;bcc[u].push_back(Edge(u, v, w, 0));}}int ans;int dfs(int u, int f) {int Min1 = INF, Min2 = INF;for (int i = 0; i < bcc[u].size(); i++) {int v = bcc[u][i].v;if (v == f) continue;Min2 = min(min(dfs(v, u), bcc[u][i].val), Min2);if (Min2 < Min1) swap(Min1, Min2);}ans = min(ans, Min2);return Min1;}int main() {while (~scanf("%d%d", &n, &m)) {init();int u, v, w;for (int i = 0; i < m; i++) {scanf("%d%d%d", &u, &v, &w);if (u > n || v > n) continue;add_edge(u, v, w, i);add_edge(v, u, w, i);}find_cut();find_bcc();if (bccn == 1) {printf("-1\n");continue;}ans = INF;u = bccno[Mine.u]; v = bccno[Mine.v];dfs(u, v);dfs(v, u);if (ans == INF) ans = -1;printf("%d\n", ans);}return 0;}
HDU 4005 the war)