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)
题目大概是给一张图,动态加边动态求割边数. 本想着求出边双连通分量后缩点,然后构成的树用树链剖分+线段树去维护路径上的边数和..好像好难写.. 看了别人的解法,这题有更简单的算法: 在任意两点添边,那 ...
随机推荐
- SpringMVC 返回自定义属性名
SpringMVC 返回的属性名默认是小写驼峰形式的实体对象中的属性名,如 userID 属性名它会返回 userId. 如果接口方式之前已经定下来,这样前端按原来的方式取数据会读取失败的,那有没有方 ...
- 学习笔记:SVG和Canvas
SVG SVG 与 Flash 类似,都是用于二维矢量图形,二者的区别在于,SVG 是一个 W3C 标准,基于 XML,是开放的.因为是 W3C 标准,SVG 与其他的 W3C 标准,比如 CSS.D ...
- 洛谷 P1281 书的复制
书的复制 Code: #include <iostream> #include <cstdio> #include <cstring> using namespac ...
- Linux文件的三个时间属性(Atime,Mtime,Ctime)
Linux下,一个文件有三种时间,分别是: 访问时间:atime 修改时间:mtime 状态时间:ctime 访问时间:对文件进行一次读操作,它的访问时间就会改变.例如像:cat.more等操作,但是 ...
- Java interface和abstract小记
一.abstract 用abstract修饰的类叫做抽象类,用abstract修饰的方法叫抽象方法. 含有抽象方法的类必须被声明为抽象类,抽象类必须被继承,抽象方法必须被重写. 抽象类不能被实例化. ...
- centos开机启动自定义脚本
有些时候我们需要在服务器里设置一个脚本,让他一开机就自己启动.方法如下: cd /etc/init.d vi youshell.sh #将youshell.sh修改为你自己的脚本名 编写自己的脚本后保 ...
- LeetCode Remove Duplicates from Sorted List 删除有序链表中的重复结点
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode ...
- 常用宏OC
#ifndef MacroDefinition_h #define MacroDefinition_h //-------------------获取设备大小--------------------- ...
- 忽略mysql库的同步
忽略mysql库的同步,请使用: stop slave sql_thread; change replication filter replicate_ignore_db=(mysql);
- Codeforces Round #324 (Div. 2) A B C D E
A,水题不多说. #include<bits/stdc++.h> using namespace std; //#define LOCAL int main() { #ifdef LOCA ...