Hdu4005-The war(双连通缩点)
Input
Output
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
题意: 敌人在N个点间建了M条线路,每条线路都有一个权值,敌人要再建一条线路,己方可以毁掉敌方的一条线路,问己方最少要花多少钱(至少得准备多少钱)才能使
这些点不连通。
解析: 先分离出每个双连通分量(删除双联通分量中的任何一条边还是连通的,没有意义),给每个分量重新编一个号,缩成一个点,在Tarjan算法过程中把桥保存下来。
选一条权值最小的桥,分别从两头出发,找次小的桥。答案就是次小的桥的权值,为甚么是找次小的桥,因为如果敌人是把最小的桥所连的两个连通分量再加一条边,则
必须删次小的桥,如果是其他,则只需要删最小的桥即可。
代码
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<sstream>
#include<algorithm>
#include<utility>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<cmath>
#include<iterator>
#include<stack>
using namespace std;
typedef __int64 LL;
const int INF=1e9+;
const double eps=1e-;
const int maxn=;
const int maxm=;
int N,M,eid,id,top;
int scc_id,scc[maxn],dfn[maxn],low[maxn],b[maxn],fa[maxn];
int head[maxn],KK[maxn];
struct edge
{
int v,w,next;
edge(int v=,int w=,int next=-):v(v),w(w),next(next){}
}E[*maxm];
struct node
{
int u,v,w;
node(int u=,int v=,int w=):u(u),v(v),w(w){}
};
vector<node> V;
void init()
{
eid=id=top=scc_id=;
for(int i=;i<=N;i++)
{
head[i]=-;
dfn[i]=low[i]=b[i]=scc[i]=;
fa[i]=i;
}
V.clear();
}
void AddEdge(int u,int v,int w)
{
E[++eid]=edge(v,w,head[u]);
head[u]=eid;
}
void Tarjan(int u)
{
dfn[u]=low[u]=++id;
KK[top++]=u;
bool first=false;
for(int i=head[u];i!=-;i=E[i].next)
{
edge& e=E[i];
int v=e.v,w=e.w;
if(v==fa[u]&&!first){ first=true; continue; }
if(!dfn[v])
{
fa[v]=u;
Tarjan(v);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u]) V.push_back(node(u,v,w));//这条边是桥
}
else low[u]=min(low[u],dfn[v]);
}
int t;
if(dfn[u]==low[u])
{
scc_id++; //双连通分量
do
{
t=KK[--top];
b[t]=scc_id; //连通分量编号
}while(u!=t);
}
return;
}
int ans;
int FindPath(int u,int pre)
{
int Min=INF,MMin=INF;
for(int i=head[u];i!=-;i=E[i].next)
{
int v=E[i].v,w=E[i].w;
if(v==pre) continue;
int t=FindPath(v,u);
if(t<MMin) MMin=t;
if(w<MMin) MMin=w;
if(Min>MMin) swap(Min,MMin);
}
ans=min(ans,MMin);
return Min;
}
int main()
{
while(scanf("%d%d",&N,&M)!=EOF)
{
init();
int u,v,w;
for(int i=;i<=M;i++)
{
scanf("%d%d%d",&u,&v,&w);
AddEdge(u,v,w); //建边
AddEdge(v,u,w); //反向边
}
for(int i=;i<=N;i++) if(!dfn[i]) Tarjan(i); //找连通分量 int mindist=INF,picku,pickv,Size=V.size();
eid=;
memset(head,-,sizeof(head));
for(int i=;i<Size;i++) //重新建图
{
node& t=V[i];
int u=t.u,v=t.v,w=t.w;
AddEdge(b[u],b[v],w);
AddEdge(b[v],b[u],w);
if(w<mindist){ mindist=w,picku=b[u],pickv=b[v]; } //权值最小的桥
}
ans=INF;
FindPath(picku,pickv);
FindPath(pickv,picku);
if(ans==INF) printf("-1\n");
else printf("%d\n",ans);
}
return ;
}
Hdu4005-The war(双连通缩点)的更多相关文章
- HDU 4005 The war(双连通好题)
HDU 4005 The war pid=4005" target="_blank" style="">题目链接 题意:给一个连通的无向图.每条 ...
- hdu 4612 Warm up 双连通缩点+树的直径
首先双连通缩点建立新图(顺带求原图的总的桥数,事实上因为原图是一个强连通图,所以桥就等于缩点后的边) 此时得到的图类似树结构,对于新图求一次直径,也就是最长链. 我们新建的边就一定是连接这条最长链的首 ...
- 边双连通缩点+树dp 2015 ACM Arabella Collegiate Programming Contest的Gym - 100676H
http://codeforces.com/gym/100676/attachments 题目大意: 有n个城市,有m条路,每条路都有边长,如果某几个城市的路能组成一个环,那么在环中的这些城市就有传送 ...
- POJ 3177 Redundant Paths (边双连通+缩点)
<题目链接> <转载于 >>> > 题目大意: 有n个牧场,Bessie 要从一个牧场到另一个牧场,要求至少要有2条独立的路可以走.现已有m条路,求至少要新 ...
- UVA 10972 RevolC FaeLoN(边-双连通+缩点)
很好的一道图论题,整整撸了一上午... 题意是给定一个无向图,要求将所有边变为有向边,求最少加入多少条有向边,使得该图强连通?这里先假设一个问题:给定一个无向子图,该子图具有怎样的性质才能使得将其无向 ...
- POJ - 3177 Redundant Paths (边双连通缩点)
题意:在一张图中最少可以添加几条边,使其中任意两点间都有两条不重复的路径(路径中任意一条边都不同). 分析:问题就是最少添加几条边,使其成为边双连通图.可以先将图中所有边双连通分量缩点,之后得到的就是 ...
- poj 3352 Road Construction【边双连通求最少加多少条边使图双连通&&缩点】
Road Construction Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10141 Accepted: 503 ...
- HDU 4005 The war 双连通分量 缩点
题意: 有一个边带权的无向图,敌人可以任意在图中加一条边,然后你可以选择删除任意一条边使得图不连通,费用为被删除的边的权值. 求敌人在最优的情况下,使图不连通的最小费用. 分析: 首先求出边双连通分量 ...
- UVA-10972 RevolC FaeLoN (边双连通+缩点)
题目大意:将n个点,m条边的无向图变成强连通图,最少需要加几条有向边. 题目分析:所谓强连通,就是无向图中任意两点可互达.找出所有的边连通分量,每一个边连通分量都是强连通的,那么缩点得到bcc图,只需 ...
随机推荐
- Android设置定时执行执行一次任务
private Handler handler = new Handler(){ public void handleMessage(Message msg) { super.handleMessag ...
- SQLSERVER 跨服 跨库
一.同服务器 select * from 数据库名.dbo.表名 select * from 数据库名..表名 dbo可以省略,点不能. 二.不同服务器 --新增服务器连接exec sp_addlin ...
- 嵌入式开发——boa服务器下的ajax与cgi通信
博主最近在最有做一个嵌入式课程设计,要求是利用基于cortax a8的物联网实验箱做一个简单的嵌入式网页交互系统作为课程设计来验收评分.因为本身自己是学前端的,所以网页部分并不是重点,主要是和boa服 ...
- 洛谷 P3383 【模板】线性筛素数
P3383 [模板]线性筛素数 题目描述 如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内) 输入输出格式 输入格式: 第一行包含两个正整数N.M,分别表示查询的范 ...
- 如何在WebSocket类中访问Session
我最近正在做一个基于websocket的webQQ,最后代码会开源带github上,所以过程中我就不贴所有的代码啦~就贴问题的关键. 我在WebSocket里发消息的时候需要用到session,因为在 ...
- jQuery 文字截取
HTML <div class="summary"> <p class="news">业内知道,当赵科林“过档”联想之初,恰逢联想 ...
- Python操作 Memcache、Redis、RabbitMQ、SQLAlchemy
Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度 ...
- 列表:一个打了激素的数组2 - 零基础入门学习Python011
列表:一个打了激素的数组2 让编程改变世界 Change the world by program 从列表中获取元素 跟数组一样,我们可以通过元素的索引值(index)从列表获取单个元素,注意,列表索 ...
- [CSAPP]并发与并行
学了这么久的计算机,并发与并行的概念理解的一直不够透彻.考研复习那会儿,以为自己懂了,然而直到看了CSAPP才算是真正明白了这俩个概念. 并发(concurrency) 流X和流Y并发运行是指,流X在 ...
- [Google Code Jam (Round 1A 2008) ] A. Minimum Scalar Product
Problem A. Minimum Scalar Product This contest is open for practice. You can try every problem as ...