HDU 4005 The war

pid=4005" target="_blank" style="">题目链接

题意:给一个连通的无向图。每条边有一个炸掉的代价。如今要建一条边(你不不知道的),然后你要求一个你须要的最少代价,保证无论他建在哪,你都能炸掉使得图不连通

思路:炸肯定要炸桥,所以先双连通缩点,得到一棵树,树边是要炸的,那么找一个最小值的边。从该边的两点出发。走的路径中,把两条包括最小值的路径。的两点连边。形成一个环。这个环就保证了最低代价在里面。除了这个环以外的最小边。就是答案,这种话,就利用一个dfs,搜到每一个子树的时候进行一个维护就可以

代码:

#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;
}

最新文章

  1. 【类库】容器对象(List、DataTable、 DataView、Dictionary)
  2. LEETCODE —— Sudoku Solver
  3. 设计一个较好的框架的难点之一--API兼容性的设计
  4. 理解linux and inode
  5. java中的[Ljava.lang.Object;@2a139a55问题
  6. 7.29 H5学习笔记
  7. C++ Base64 编码 解码
  8. FragmentTabHost+ViewPager实现底部按钮
  9. 161123、ssh scp 复制文件和文件夹
  10. new trip
  11. IntelliJ IDEA 13.x 下使用Hibernate + Spring MVC + JBoss 7.1.1
  12. 关于I/O的那点事
  13. Choose the best route
  14. linux下C++ STL hash_map的使用以及使用char *型变量作为Key值的一大“坑”
  15. linux history 命令详解
  16. python/MySQL(索引、执行计划、BDA、分页)
  17. Java工程师成神之路思维导图
  18. Java集合中的细节
  19. python 全栈开发笔记 3
  20. 安装VMware tools

热门文章

  1. LN : leetcode 53 Maximum Subarray
  2. LN : leetcode 283 Move Zeroes
  3. es6 export-from用法
  4. hihocoder offer收割编程练习赛13 D 骑士游历
  5. Framework7首页隐藏navbar
  6. Android电池电量跳变
  7. github与git常用的一些基本配置与命令
  8. 02C++基本语法
  9. BZOJ 2223: [Coci 2009]PATULJCI 主席树
  10. scala学习(3)-----wordcount【sparksession】