The war

Problem Description
 
In the war, the intelligence about the enemy is very important. Now, our troop has mastered the situation of the enemy's war zones, and known that these war zones can communicate to each other directly or indirectly through the network. We also know the enemy is going to build a new communication line to strengthen their communication network. Our task is to destroy their communication network, so that some of their war zones can't communicate. Each line has its "cost of destroy". If we want to destroy a line, we must spend the "cost of destroy" of this line. We want to finish this task using the least cost, but our enemy is very clever. Now, we know the network they have already built, but we know nothing about the new line which our enemy is going to build. In this condition, your task is to find the minimum cost that no matter where our enemy builds the new line, you can destroy it using the fixed money. Please give the minimum cost. For efficiency, we can only destroy one communication line.
 
Input
 
The input contains several cases. For each cases, the first line contains two positive integers n, m (1<=n<=10000, 0<=m<=100000) standing for the number of the enemy's war zones (numbered from 1 to n), and the number of lines that our enemy has already build. Then m lines follow. For each line there are three positive integer a, b, c (1<=a, b<=n, 1<=c<=100000), meaning between war zone A and war zone B there is a communication line with the "cost of destroy " c.
 
Output
For each case, if the task can be finished output the minimum cost, or output ‐1.
 
Sample Input
 
3 2
1 2 1
2 3 2
4 3
1 2 1
1 3 2
1 4 3
 
Sample Output
 
-1
3
 
Hint

For the second sample input: our enemy may build line 2 to 3, 2 to 4,

3 to 4. If they build line 2 to 3, we will destroy line 1 to 4, cost 3. If they

build line 2 to 4, we will destroy line 1 to 3, cost 2. If they build line 3 to 4,

we will destroy line 1 to 2, cost 1. So, if we want to make sure that we can

destroy successfully, the minimum cost is 3.

 
 
题意:
  给你一个n点m边的无向图
  有边权
  现在你可以选任意两个没有边相连的点连一条边,求新图的割边最小边的最大值
题解:
  考虑缩环之后就是一个树
  加一条边形成环,那么这个原树的最小边必然要在这个环内才能使得答案更加优
  找到这条边的两个端点,dfs这两个点,尽量走含有边权最小的链,这个dp处理即可
  dp[u][0/1]分别表示从u这个点开始走一条链含有的最小值和次小值
  最后就是两个端点走出的链的次小值取最小就是答案
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
const long long INF = 1e18;
const double Pi = acos(-1.0);
const int N = 1e4+, M = 1e5, mod = 1e9+, inf = 2e9; int ans,scc,t,top,tot,head[N],n,m,dp[N][],a[N],b[N],c[N];
struct edge{int id,to,next,value;}e[M]; void add(int u,int v,int w) {e[t].next = head[u];e[t].to=v;e[t].value=w;e[t].id=;head[u]=t++;} int dfn[N],q[N],inq[N],low[N],belong[N],hav[N]; vector<pair<int ,int > > G[N];
void init() {
for(int i = ; i <= n; ++i) dp[i][] = dp[i][] = inf;
for(int i = ; i <= n; ++i) G[i].clear();
memset(hav,,sizeof(hav));
memset(dfn,,sizeof(dfn));
memset(head,-,sizeof(head));
t = tot = top = scc = ;
}
void dfs(int u) {
low[u] = dfn[u] = ++tot;
q[++top] = u; inq[u] = ;
for(int i = head[u]; i!=-; i = e[i].next) {
int to = e[i].to;
if(e[i].id) continue;
e[i].id = e[i ^ ].id = ;
if(!dfn[to]) {
dfs(to);
low[u] = min(low[u],low[to]);
} else if(inq[to]) low[u] = min(low[u],dfn[to]);
}
if(low[u] == dfn[u]) {
scc++;
do{
inq[q[top]] = ;
belong[q[top]] = scc;
}while(u != q[top--]);
}
}
void dfs_ans(int u,int fa) {
if(u == -) return ;
int fi = ;
for(int i = ; i < G[u].size(); ++i) {
int to = G[u][i].first;
int value = G[u][i].second;
if(to == fa) continue;
dfs_ans(to,u);
if(!fi) {
dp[u][] = min(value,dp[to][]);
dp[u][] = dp[to][];
fi = ;
} else {
if(min(value,dp[to][]) < dp[u][]) dp[u][] = min(dp[u][],min(dp[to][],dp[u][])),dp[u][] = min(value,dp[to][]);
else dp[u][] = min(dp[u][],min(value,dp[to][]));
}
}
}
void Tarjan() {
int mi = inf, s = -, t = -;
for(int i = ; i <= n; ++i) if(!dfn[i]) dfs(i);
for(int i = ; i <= m; ++i) {
int fx = belong[a[i]];
int fy = belong[b[i]];
if(fx != fy) {
G[fx].push_back(MP(fy,c[i]));
G[fy].push_back(MP(fx,c[i]));
// cout<<fx<<" "<<fy<<endl;
if(c[i] < mi) {
s = fx,t = fy;
mi = c[i];
}
}
}
ans = inf;
dfs_ans(s,t);
dfs_ans(t,s);
if(s != - && t != -)ans = min(dp[s][],dp[t][]);
if(ans == inf) printf("%d\n",-);
else printf("%d\n",ans);
}
int main() {
while(~scanf("%d%d",&n,&m)) {
init();
for(int i = ; i <= m; ++i) {
scanf("%d%d%d",&a[i],&b[i],&c[i]);
add(a[i],b[i],c[i]);add(b[i],a[i],c[i]);
}
Tarjan();
}
return ;
}

HDU 4005 The war Tarjan+dp的更多相关文章

  1. HDU 4005 The war(双连通好题)

    HDU 4005 The war pid=4005" target="_blank" style="">题目链接 题意:给一个连通的无向图.每条 ...

  2. HDU 4005 The war (图论-tarjan)

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

  3. hdu 4005 The war

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

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

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

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

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

  6. HDU 1003 Max Sum --- 经典DP

    HDU 1003    相关链接   HDU 1231题解 题目大意:给定序列个数n及n个数,求该序列的最大连续子序列的和,要求输出最大连续子序列的和以及子序列的首位位置 解题思路:经典DP,可以定义 ...

  7. hdu 5094 Maze 状态压缩dp+广搜

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092176.html 题目链接:hdu 5094 Maze 状态压缩dp+广搜 使用广度优先 ...

  8. BZOJ 1093: [ZJOI2007]最大半连通子图( tarjan + dp )

    WA了好多次... 先tarjan缩点, 然后题意就是求DAG上的一条最长链. dp(u) = max{dp(v)} + totu, edge(u,v)存在. totu是scc(u)的结点数. 其实就 ...

  9. hdu 2829 Lawrence(斜率优化DP)

    题目链接:hdu 2829 Lawrence 题意: 在一条直线型的铁路上,每个站点有各自的权重num[i],每一段铁路(边)的权重(题目上说是战略价值什么的好像)是能经过这条边的所有站点的乘积之和. ...

随机推荐

  1. SHAREPOINT - CAML列表查询

    首先要了解的是CAML(Collaboration Application Markup Language)不仅仅是用在对列表.文档库的查询,字段的定义,站点定义等处处使用的都是CAML. 简单的提一 ...

  2. 【leetcode】Maximum Subarray

    Maximum Subarray Find the contiguous subarray within an array (containing at least one number) which ...

  3. python之打包相关

    打包手册:https://python-packaging-user-guide.readthedocs.org/en/latest/installing.html#installing-from-a ...

  4. struct vs class

    关于默认访问权限class中默认的成员访问权限是private的,而struct中则是public的. 关于继承方式class继承默认是private继承,而struct继承默认是public继承. ...

  5. fork详解

    [本文链接] http://www.cnblogs.com/hellogiser/p/fork.html [代码] 下面的代码输出多少个-?  C++ Code  123456789101112131 ...

  6. Java for LeetCode 226 Invert Binary Tree

    Invert a binary tree. 4 / \ 2 7 / \ / \ 1 3 6 9 to 4 / \ 7 2 / \ / \ 9 6 3 1 Trivia: This problem wa ...

  7. codeforces 500A. New Year Transportation

    题目链接:http://codeforces.com/problemset/problem/500/A 题目意思:给出 n-1 个 cell,每个 cell 有一个值 ai,表示在这个编号为 i 的 ...

  8. 【hadoop2.6.0】数据丢失问题解决

    想自己走一遍从代码到运行的流程,结果各种错,郁闷啊. 问题① http://localhost:50070/ 里面一进去就告诉我块丢了.... 解决: bin/hadoop fsck -delete ...

  9. 129. Sum Root to Leaf Numbers

    题目: Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a nu ...

  10. September 19th 2016 Week 39th Monday

    We come nearest to the great when we are great in humility. 我们最为谦逊的时候越接近伟大. When you are powerful en ...