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. POJ 3414

    http://poj.org/problem?id=3414 这是一个广搜的题目,不难,就是有些许麻烦.对于练习还是个不错的题目. 题意就是给你两个杯子,这两个杯子的容量分别为a和b,要你通过一些操作 ...

  2. cf219d

    树形dp #include <cstdio> #include <vector> using namespace std; #define D(x) const int INF ...

  3. eclipse中手动导入DTD文件的方式

    DTD一般应用在应用程序中定义数据交换类型的文档,一般用在xml配置文件中,有些时候在eclipse中并不能加载一些提示,这个时候需要手动导入,导入方法如下: 1.首先根据声明的网址下载.dtd的文件 ...

  4. 【hiho一下第77周】递归-减而治之 (MS面试题:Koch Snowflake)

    本题是一道微软面试题,看起来复杂,解出来会发现其实是一个很简单的递归问题,但是这道题的递归思路是很值得我们反复推敲的. 原题为hihocoder第77周的题目. 描述 Koch Snowflake i ...

  5. 16. javacript高级程序设计-HTML5脚本编程

    1. HTML5脚本编程 l 跨文档消息传递API能够让我们在不降低同源策略安全性的前提下,在来至不同的域的文档间传递消息 l 原生拖放功能可以方便的指定某个元素是否可以拖动,并在放置时做出响应.还可 ...

  6. 请确认 <Import> 声明中的路径正确,且磁盘上存在该文件。

    在网上下了个源码打开报错. 请确认 <Import> 声明中的路径正确,且磁盘上存在该文件. 一查,原来是路径错误. 解决办法:将项目文件(.csproj)用记事本打开,然后找到<I ...

  7. Spring@Autowired注解与自动装配

    1   配置文件的方法 我们编写spring 框架的代码时候.一直遵循是这样一个规则:所有在spring中注入的bean 都建议定义成私有的域变量.并且要配套写上 get 和 set方法. Boss ...

  8. jquery的基本事件大全

    ].name); });jQuery.getScript( url, [callback] ) 使用GET请求javascript文件并执行. $.getScript(”test.js”, funct ...

  9. 【leetcode】Linked List Cycle II (middle)

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Foll ...

  10. CodeForces 407B Long Path (DP)

    题目链接 题意:一共n+1个房间,一个人从1走到n+1,如果第奇数次走到房间i,会退回到房间Pi,如果偶数次走到房间i,则走到房间i+1,问走到n+1需要多少步,结果对1e9+7取模. 题解:设dp[ ...