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)
题目大概是给一张图,动态加边动态求割边数. 本想着求出边双连通分量后缩点,然后构成的树用树链剖分+线段树去维护路径上的边数和..好像好难写.. 看了别人的解法,这题有更简单的算法: 在任意两点添边,那 ...
随机推荐
- Laravel项目的结构文章
http://esbenp.github.io/2016/04/11/modern-rest-api-laravel-part-1/
- jar 压缩 解压 war包
Win+R 输入cmd进入命令行,进入到源码所在目录.所用工具,jdk自带的jar.exe 打包命令:jar -cvf xxx.war * 解包命令: jar -xvf xxx.war * 参数 说明 ...
- servlet传值到servlet传值问题
今天在项目中遇到一个问题:中期项目自己做的新闻部分NewsPagerSortservlet传值时,正确答案如下 if(title!=""){ resp.sendRedirect(& ...
- JS中关于clientWidth offsetWidth scrollWidth 等的区别
网页可见区域宽: document.body.clientWidth;网页可见区域高: document.body.clientHeight;网页可见区域宽: document.body.offset ...
- GitLab关于SSH的使用
SSH Git是分布式版本控制系统,这意味着您可以在本地工作,但您也可以将更改共享或“推送”到其他服务器.在将更改推送到GitLab服务器之前,您需要一个用于共享信息的安全通信通道. SSH协议提供此 ...
- Android应用瘦身
转:https://zhuanlan.zhihu.com/p/25465537 瘦身的目的 从目的导向来看,我们是不会无缘无故去做一件事情的,那我们对应用瘦身的目的是为了什么?答案是:提高下载转化率. ...
- Oracle数据库基础--建表语法+操作
语法 1.建表 create table 表名( 列名 数据类型, …… ); 2.删除表:drop table 表名; 3.添加列:alter table 表名 add(列名 数据类型); 4.修改 ...
- DDL与DML语句
1. DDL语句 SQL语句:结构化查询语句,使用SQL与数据库“沟通”,完成相应的数据库操作. l DDL:数据定义语言,用来维护数据库对象 1.1 创建表 Ø CREATE:创建表 演示:创建员工 ...
- 利用photoshop制作gif图片
首先准备你需要的几张素材图片 1.将素材图片根据发生的顺序放置在不同的图层 2.打开窗口下的时间轴 选择帧动画 3.创建第一张帧动画 选项卡右边这个按钮,点击这个选择新建帧 第一张图片显示其他的隐藏 ...
- python_40_通过脚本转换参数实现替换
import sys f=open('yesterday','r',encoding='utf-8') f_new=open('yesterday_update','w',encoding='utf- ...