HDU 4005 The war 双连通分量 缩点
题意:
有一个边带权的无向图,敌人可以任意在图中加一条边,然后你可以选择删除任意一条边使得图不连通,费用为被删除的边的权值。
求敌人在最优的情况下,使图不连通的最小费用。
分析:
首先求出边双连通分量,缩点成树。
敌人如果选则树中\(u,v\)节点之间加一条边,则路径\(u \to v\)中所有的边都会变成环。
我们只能考虑删除其他的权值最小的边使图不连通。
从敌人的角度考虑:如果使树中权值最小的边成环,那么我们的费用会增加。在最小边成环的前提下,如果还能使次小边也成环,我们的费用又会增加,以此类推。
因此先找到最小边,然后从这条边两头DFS,肯定选择最小值所在的子树延长路径,然后用其他子树中的最小边更新答案。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 10000 + 10;
const int maxm = 200000 + 10;
struct Edge
{
int v, w, nxt;
Edge() {}
Edge(int v, int w, int nxt): v(v), w(w), nxt(nxt) {}
};
struct Graph
{
int ecnt, head[maxn];
Edge edges[maxm];
void init() { ecnt = 0; memset(head, -1, sizeof(head)); }
void AddEdge(int u, int v, int w) {
edges[ecnt] = Edge(v, w, head[u]);
head[u] = ecnt++;
}
};
Graph g, t;
int n, m;
stack<int> S;
int dfs_clock, pre[maxn], low[maxn];
int scc_cnt, sccno[maxn];
void dfs(int u, int fa) {
pre[u] = low[u] = ++dfs_clock;
S.push(u);
bool flag = false;
for(int i = g.head[u]; ~i; i = g.edges[i].nxt) {
int v = g.edges[i].v;
if(v == fa && !flag) { flag = true; continue; }
if(!pre[v]) {
dfs(v, u);
low[u] = min(low[u], low[v]);
} else if(!sccno[v]) low[u] = min(low[u], pre[v]);
}
if(low[u] == pre[u]) {
scc_cnt++;
for(;;) {
int x = S.top(); S.pop();
sccno[x] = scc_cnt;
if(x == u) break;
}
}
}
void find_scc() {
memset(pre, 0, sizeof(pre));
memset(sccno, 0, sizeof(sccno));
dfs_clock = scc_cnt = 0;
dfs(1, 0);
}
int ans;
int dfs2(int u, int fa) {
int min1 = INF, min2 = INF;
for(int i = t.head[u]; ~i; i = t.edges[i].nxt) {
int v = t.edges[i].v;
if(v == fa) continue;
int tmp = t.edges[i].w;
tmp = min(tmp, dfs2(v, u));
if(tmp < min2) min2 = tmp;
if(min2 < min1) swap(min1, min2);
}
ans = min(ans, min2);
return min1;
}
int main()
{
while(scanf("%d%d", &n, &m) == 2) {
g.init();
while(m--) {
int u, v, w; scanf("%d%d%d", &u, &v, &w);
g.AddEdge(u, v, w);
g.AddEdge(v, u, w);
}
find_scc();
t.init();
int a, b, minEdge = INF;
for(int u = 1; u <= n; u++) {
for(int i = g.head[u]; ~i; i = g.edges[i].nxt) {
int v = g.edges[i].v;
if(sccno[u] == sccno[v]) continue;
int w = g.edges[i].w;
t.AddEdge(sccno[u], sccno[v], w);
if(w < minEdge) { minEdge = w; a = sccno[u]; b = sccno[v]; }
}
}
ans = INF;
dfs2(a, b);
dfs2(b, a);
if(ans == INF) ans = -1;
printf("%d\n", ans);
}
return 0;
}
HDU 4005 The war 双连通分量 缩点的更多相关文章
- HDU 4005 The war(双连通好题)
HDU 4005 The war pid=4005" target="_blank" style="">题目链接 题意:给一个连通的无向图.每条 ...
- HDU 2460 Network 边双连通分量 缩点
题意: 给出一个无向连通图,有\(m\)次操作,每次在\(u, v\)之间加一条边,并输出此时图中桥的个数. 分析: 先找出边双连通分量然后缩点得到一棵树,树上的每条边都输原图中的桥,因此此时桥的个数 ...
- HDU 3686 Traffic Real Time Query System(双连通分量缩点+LCA)(2010 Asia Hangzhou Regional Contest)
Problem Description City C is really a nightmare of all drivers for its traffic jams. To solve the t ...
- POJ3177 Redundant Paths(边双连通分量+缩点)
题目大概是给一个无向连通图,问最少加几条边,使图的任意两点都至少有两条边不重复路径. 如果一个图是边双连通图,即不存在割边,那么任何两个点都满足至少有两条边不重复路径,因为假设有重复边那这条边一定就是 ...
- 训练指南 UVA - 11324(双连通分量 + 缩点+ 基础DP)
layout: post title: 训练指南 UVA - 11324(双连通分量 + 缩点+ 基础DP) author: "luowentaoaa" catalog: true ...
- HDU 4612 Warm up (边双连通分量+缩点+树的直径)
<题目链接> 题目大意:给出一个连通图,问你在这个连通图上加一条边,使该连通图的桥的数量最小,输出最少的桥的数量. 解题分析: 首先,通过Tarjan缩点,将该图缩成一颗树,树上的每个节点 ...
- HDU 5458 Stability(双连通分量+LCA+并查集+树状数组)(2015 ACM/ICPC Asia Regional Shenyang Online)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5458 Problem Description Given an undirected connecte ...
- Hdu4005-The war(双连通缩点)
In the war, the intelligence about the enemy is very important. Now, our troop has mastered the situ ...
- POJ3694 Network(边双连通分量+缩点+LCA)
题目大概是给一张图,动态加边动态求割边数. 本想着求出边双连通分量后缩点,然后构成的树用树链剖分+线段树去维护路径上的边数和..好像好难写.. 看了别人的解法,这题有更简单的算法: 在任意两点添边,那 ...
随机推荐
- window.open()方法详解
, 最基本的弹出窗口代码 window.open('page.html'); 2, 经过设置后的弹出窗口 window.open('page.html', 'newwindow', 'heig ...
- ubuntu16.04解决屏幕适应问题
打开ubuntu登录进去后,输入: sudo apt-get installopen-vm-tools sudo apt-get install open-vm* 然后重启(reboot),即可解决 ...
- Yii2 widgets [mztest/yii2-widget-file-upload]
Enjoy it. A widget for uploading files to your server. Github , Packagist Screenshots
- C++ list类详解
转自:http://blog.csdn.net/whz_zb/article/details/6831817 双向循环链表list list是双向循环链表,,每一个元素都知道前面一个元素和后面一个元素 ...
- C#调用Python脚本并使用Python的第三方模块
[转载]http://zh.5long.me/2015/dotnet-call-python/ 前言 InronPython是一种在.NET和Mono上实现的Python语言,使用InronPytho ...
- Extjs4.1+desktop+SSH2 搭建环境 项目能跑起来
linux开发感觉可能就是日常办公的时候,用别的软件会有问题,java开发还是没什么区别的,换回window开发: push 它: 每次看到右上那红红的叉,我还以为又出错了: 这个项目用resin,下 ...
- 关于wp8.1 runtime模式下面的摄像头调用拍照问题和应用生命周期问题
现在的msdn文档,还找不到详细的wp8.1的摄像头拍照文档,只有一个序列拍照,类似九连拍的文档,而且这文档感觉就是windows8.1搬过来应付的,wp8.1模式,只要有一个地方处理不好,手机就会死 ...
- slenium的xpath几种定位方式
练习地址,以下面地址为例: http://www.w3school.com.cn/example/xmle/books.xml 1. 查找book对象 //book #所有的数 //book[1] ...
- iOS 集成支付宝过程中 我遇到的一些坑,请大家注意啦(ALI69错误,ALI64错误)
支付宝很早一段时间就集成了,之前由于一直忙于开发就没有总结,今天整理桌面的时候看到,当时做支付时候的一些散落的笔记,就稍微整理一下,给大家分享一下. 第一:当时调用支付宝的时候,总是调不起来,进过断点 ...
- PHP数组排序方法总结
随着PHP的快速发展,用它的人越来越多,在PHP数组学习摘录部分了解到最基本的PHP数组的建立和数组元素的显示.需要深入学习下PHP数组的相关操作.首先接触的就是PHP数组排序.降序的排序问题. so ...