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

HDU 4005 The war(双连通好题)的更多相关文章

  1. HDU 4005 The war 双连通分量 缩点

    题意: 有一个边带权的无向图,敌人可以任意在图中加一条边,然后你可以选择删除任意一条边使得图不连通,费用为被删除的边的权值. 求敌人在最优的情况下,使图不连通的最小费用. 分析: 首先求出边双连通分量 ...

  2. HDU 4738 双连通模版题

    九野的博客,转载请注明出处:http://blog.csdn.net/acmmmm/article/details/11711577 题意:给定n个点,m条无向边 下面m行表示u , v ,边权值 求 ...

  3. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  4. hdu 4612 Warm up 双连通缩点+树的直径

    首先双连通缩点建立新图(顺带求原图的总的桥数,事实上因为原图是一个强连通图,所以桥就等于缩点后的边) 此时得到的图类似树结构,对于新图求一次直径,也就是最长链. 我们新建的边就一定是连接这条最长链的首 ...

  5. HDU 4005 The war(边双连通)

    题意 ​ 给定一张 \(n\) 个点 \(m\) 条边的无向连通图,加入一条边,使得图中权值最小的桥权值最大,如果能使图中没有桥则输出 \(-1\). 思路 ​ 先对原图边双缩点,然后变成了一棵树.在 ...

  6. hdu 4005 The war

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4005 In the war, the intelligence about the enemy is ...

  7. Hdu4005-The war(双连通缩点)

    In the war, the intelligence about the enemy is very important. Now, our troop has mastered the situ ...

  8. HDU 4005 The war Tarjan+dp

    The war Problem Description   In the war, the intelligence about the enemy is very important. Now, o ...

  9. hdu 4612 Warm up 双连通+树形dp思想

    Warm up Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total S ...

随机推荐

  1. Git学习笔记(0)-错误汇总

    一.LF will be replaced by CRLF 1.发现问题 $ git add welcome.txt warning: LF will be replaced by CRLF in w ...

  2. 专题十二:实现一个简单的FTP服务器

    引言: 在本专题中将和大家分享如何自己实现一个简单的FTP服务器.在我们平时的上网过程中,一般都是使用FTP的客户端来对商家提供的服务器进行访问(上传.下载文件),例如我们经常用到微软的SkyDriv ...

  3. ubuntu下编译VLC源码

    http://blog.csdn.net/beitiandijun/article/details/9225591ubuntu下编译VLC源码 分类: 视频处理 2013-07-02 17:33 57 ...

  4. springboot项目中,@transactional 无效

    问题: springboot项目,依然是使用jpa.Hibernate来操作mysql,涉及到数据库的操作,就少不了事务.写了一个接口,用来测试@Transaction注解的作用,发现没有效果 分析: ...

  5. Detectron-MaskRCnn:Mask判别和获取前向Mask的标签

    对于FCN-SceneParse网络,最后卷积生成N个类别的maps,每个Map都得到图像所有点的单类概率.MaskRCNN的结构与FCN不相同. 参考三个文章: Detectron总结1:Blob的 ...

  6. XGBoost参数中文翻译以及参数调优

    XGBoost:参数解释:https://blog.csdn.net/zc02051126/article/details/46711047 机器学习系列(11)_Python中Gradient Bo ...

  7. jQuery元素节点的插入

    jquery插入节点的的方法,总的来说有8种,但是只要学会了其中的两个就能理解全部了, 这里我们学习append()和appendTo()两个方法: append()方法是向元素的内部追加内容: &l ...

  8. Linux:使用root踢掉其他用户

     首先使用w命令查看所有在线用户:  执行命令: pkill -kill -t tty3 再用w命令查看是否已经强制踢掉: TTY 是终端的意思    TTY :0 表示root用户登陆图形化界面的终 ...

  9. (一)python条件语句和基本数据类型

    条件语句 语法一:if...else  if <条件成立>: 处理过程 else: 处理过程 语法二:if...elif...else if <条件1成立>: 处理过程1 el ...

  10. [ural1057][Amount of Degrees] (数位dp+进制模型)

    Discription Create a code to determine the amount of integers, lying in the set [X; Y] and being a s ...