HDU 4005 The war(tarjan bcc + dp)
来源:互联网 发布:淘宝生意参谋有什么用 编辑:程序博客网 时间:2024/05/07 17:26
题意:
N<=105,M<=105的无向图,现在有可能在任意位置新建一条边,我们要删掉一条边使得图不连通,求最小花费
分析:
bcc肯定不能删边,所以先bcc缩点成树,树边都是桥都可以删除
但是怎么删除呢−−最小那条边一定会被新建的边形成的环(bcc)包括进去,懒得说了,别人写的挺清楚的
别人的题解
虽说画图可以帮助解这个题,我鬼画符了一晚上也没发现这个规律,鬼画符之前要先猜啊
代码:
//// Created by TaoSama on 2015-11-24// Copyright (c) 2015 TaoSama. All rights reserved.////#pragma comment(linker, "/STACK:1024000000,1024000000")#include <algorithm>#include <cctype>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iomanip>#include <iostream>#include <map>#include <queue>#include <string>#include <set>#include <vector>using namespace std;#define pr(x) cout << #x << " = " << x << " "#define prln(x) cout << #x << " = " << x << endlconst int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;const int M = 2e5 + 10;int n, m;struct Edge { int v, nxt, c;} edge[M], raw[M];int head[N], rawHead[N], cnt;void addRawEdge(int u, int v, int c) { raw[cnt] = (Edge) {v, rawHead[u], c}; rawHead[u] = cnt++; raw[cnt] = (Edge) {u, rawHead[v], c}; rawHead[v] = cnt++;}void addEdge(int u, int v, int c) { edge[cnt] = (Edge) {v, head[u], c}; head[u] = cnt++;}int dfn[N], low[N], in[N], id[N], bcc, dfsNum;int stk[N], top;void tarjan(int u, int f) { dfn[u] = low[u] = ++dfsNum; stk[++top] = u; in[u] = true; for(int i = rawHead[u]; ~i; i = raw[i].nxt) { int v = raw[i].v; if(i == (f ^ 1)) continue; if(!dfn[v]) { tarjan(v, i); low[u] = min(low[u], low[v]); } else if(in[v]) low[u] = min(low[u], dfn[v]); } if(low[u] == dfn[u]) { ++bcc; while(true) { int v = stk[top--]; in[v] = false; id[v] = bcc; if(v == u) break; } }}void init() { bcc = dfsNum = 0; memset(dfn, 0, sizeof dfn);}int ans, dp[N][2]; //0->minimum 1->minorvoid dfs(int u, int f) { dp[u][0] = dp[u][1] = INF; for(int i = head[u]; ~i; i = edge[i].nxt) { int v = edge[i].v; if(v == f) continue; dfs(v, u); dp[u][1] = min(dp[u][1], dp[v][0]); dp[u][1] = min(dp[u][1], edge[i].c); if(dp[u][1] < dp[u][0]) swap(dp[u][1], dp[u][0]); } ans = min(ans, dp[u][1]);}int main() {#ifdef LOCAL freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);// freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);#endif// ios_base::sync_with_stdio(0); while(scanf("%d%d", &n, &m) == 2) { cnt = 0; memset(rawHead, -1, sizeof rawHead); while(m--) { int u, v, c; scanf("%d%d%d", &u, &v, &c); addRawEdge(u, v, c); } init(); tarjan(1, -1); cnt = 0; memset(head, -1, sizeof head); int a, b, minE = INF; for(int i = 1; i <= n; ++i) { int u = id[i]; for(int j = rawHead[i]; ~j; j = raw[j].nxt) { int v = id[raw[j].v]; if(u == v) continue; addEdge(u, v, raw[j].c); if(raw[j].c < minE) { minE = raw[j].c; a = u, b = v; } } } ans = INF; dfs(a, b); dfs(b, a); if(ans == INF) ans = -1; printf("%d\n", ans); } return 0;}
0 0
- HDU 4005 The war(tarjan bcc + dp)
- HDU 4005 The war (图论-tarjan)
- HDU 2242 考研路茫茫 空调教室(tarjan bcc + tree dp)
- HDU 4005 The war
- HDU 4005 The war 边-双连通缩点+树形dp
- POJ 3177Redundant Paths (tarjan bcc)
- POJ 3694Network (tarjan bcc + LCA)
- hdu 2242 (Tarjan + 树形dp)
- HDU 4005 The war(双连通好题)
- HDU 4005 The war(边双连通+缩点)
- 【HDU】4005 The war 边双连通
- 【poj 2942 】 Knights of the Round Table 【tarjan求bcc+黑白染色判二分图】
- HDU 2242 (Tarjan双连通缩点+树形DP)
- hdu 6165 FFF at Valentine (Tarjan算法,scc+dp)
- Hdu 6162 Ch’s gift(Tarjan+dp)
- HDU - 2809 God of War (DP+状态压缩)
- HDU - 4005 The war(dfs+边双连通)
- Tarjan算法求BCC(无向图连通块、割边、割点)
- 【学习】二叉树基本操作
- Netty Sharable Handler 使用是私有变量
- 欢迎使用CSDN-markdown编辑器
- HDU 4203 Doubloon Game(博弈打表)
- JUnit简单使用教程
- HDU 4005 The war(tarjan bcc + dp)
- JVM垃圾回收介绍和总结
- uboot - 启动流程分析【第一阶段】
- Java I/O
- onSaveInstanceState和onRestoreInstanceState
- 单元测试的意义
- 算法笔记-卡尔曼滤波器简单解释
- uboot - 启动流程分析【第二阶段】
- Something trivial. Type alias and const modifier