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图,只需 ...
随机推荐
- 使用Python,字标注及最大熵法进行中文分词
使用Python,字标注及最大熵法进行中文分词 在前面的博文中使用python实现了基于词典及匹配的中文分词,这里介绍另外一种方法, 这种方法基于字标注法,并且基于最大熵法,使用机器学习方法进行训练, ...
- javascript笔记3之数据类型
/* var box = 250; //十进制整型 alert(box); var box = 070; //八进制,按照十进制输出是56 alert(box); var box = 0x1f; // ...
- 又一编辑神器-百度编辑器-Ueditor
(Lionden<hsdlionden@gmail.com> 转载说明) 前段时间发表过一篇关于“KindEditor在JSP中使用”的博文.这几天在沈阳东软进行JavaWeb方面的实习工 ...
- Hive MapJoin
摘要 MapJoin是Hive的一种优化操作,其适用于小表JOIN大表的场景,由于表的JOIN操作是在Map端且在内存进行的,所以其并不需要启动Reduce任务也就不需要经过shuffle阶段,从而能 ...
- 曾经的足迹——对Linux CAN驱动的理解(1)
在Ti的AM335X系列Cortext-A8芯片中,CAN模块采用D_CAN结构,实质即两路CAN接口. 在此分享一下对基于AM335X的Linux CAN驱动源码的理解.下面来分析它的驱动源码及其工 ...
- unity3d 学习笔记(一)
操作:按下shit 点击坐标轴中心 切换透视图 动画烘焙的概念:相当于把原来的控制器动画或者IK(骨骼)动画所有塌陷为逐帧动画,导出的时候必须选这一项 着色器:从技术的角度来看,着色器是渲染器的一个部 ...
- Android万能分辨率适应法
(1)获取屏幕的尺寸 WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE); D ...
- SqlBulkCopy的一个例子
public bool InsertAll(IList<NewStockLuoPan> list) { DataTable dt = new DataTable(); dt.Columns ...
- SQLSERVER内核架构剖析 (转)
我们做管理软件的,主要核心就在数据存储管理上.所以数据库设计是我们的重中之重.为了让我们的管理软件能够稳定.可扩展.性能优秀.可跟踪排错. 可升级部署.可插件运行,我们往往研发自己的管理软件开发平台. ...
- 将html导出到excel或word
本质是将html写成word或excel支持的html格式. 如何将html写成word或excel支持的格式? 只需打开计算机上任意一个word或excel文档,打开文件->另存为,选择文件类 ...