题意:

有一幅图,现在要加一条边,加边之后要你删除一条边,使图不连通,费用为边的费用,要你求的是删除的边的最小值的最大值(每次都可以删除一条边,选最小的删除,这些最小中的最大就为答案)

首先要进行缩点,把图缩为一棵树,因此,加入一条边后图就会存在一个环,环中的任何一条边删除后都不会导致图不连通

之后找一条最小的边,可以说这条边肯定是在加边之后的连通块里的,因为如果不在连通块里,那就直接可以把这条最小的边删掉,而达不到求出答案的目的

找到边后,分别从边的两点开始遍历,要遍历出一条路径来,并且边上的权值要尽可能的小,因为这样才能让不在环中的边尽可能的大,然后,答案就是每个 节点的次小儿子的最小值,如果没有次小儿子就不能算(就是说只有一个儿子,即节点不是三叉的),因为我完全可以把它和最小的边放到一个连通块中,那样答案 就应该更大了。

终上所述:先进行无向图的缩点,再在树上找最小的边,最后分别从边的两点出发,遍历树,找节点的次小儿子节点中的最小值

举个简单的例子(括号内的数字代表边上的权值)1和8间的权值为1,是最小的

1---8

/           \(3)

(2)/               \

2                  3

(4) /       \(5)    (6)/      \(7)

/           \         /          \

4              5     6              7

左子树中2的子节点有次小值5,右子树中3的子节点次小值为7,两个次小值间的最小值是5,即答案

现在,比如所你要把3、4连起来。我可以去掉2、5之间的边让图不连通,花费为5

把3、5连起来,我自然可以删掉2、4,花费为4,

一个节点的次小值和最小值(比如说4、5两点)不可能被同时连进一个连通块(或环)中(因为必须把最小的那条边加进环中),正是利用这个性质,不管 把那两个点连起来,我们都可以找到一个最小值或次小值来删掉使图不连通,注意:再重复一遍,同一个节点的最小值和次小值不会被加进同一个环,因此,这些次 小值中的最小的那条边的权值就是答案。(这时你如果把次小的边加进环中,如2--5,自然可以删掉一条更小的边 如2--4 使图不连通,相反,如果没有把次小的边加进去,那次小的就是答案)

思路是次要,代码要能搞出来

 #include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#define N 20100
#define M 200100
#define inf 100000000
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
int head1[N],head2[N],cnt,scc,Min;
int dfn[N],low[N],belong[N];
int dp[N];
stack<int>sta;
struct Edge{
int v,w,next;
}edge[M*]; void addedge(int u,int v,int w,int *head){
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt++;
edge[cnt].v=u;
edge[cnt].w=w;
edge[cnt].next=head[v];
head[v]=cnt++;
}
void init(int n){
memset(head1,-,sizeof(head1));
memset(head2,-,sizeof(head2));
memset(dfn,,sizeof(dfn));
for(int i=;i<=n;i++)dp[i]=inf;
cnt=scc=;
}
void DP(int u,int fa){
int i;
for(i=head2[u];i!=-;i=edge[i].next){
int v=edge[i].v;
if(v!=fa){
DP(v,u);
dp[v]=min(dp[v],edge[i].w);
if(dp[u]>dp[v]){
Min=min(Min,dp[u]);
dp[u]=dp[v];
}
else
Min=min(Min,dp[v]);
}
}
}
void tarjan(int u,int fa){
int i,flag=;
dfn[u]=low[u]=dfn[fa]+;
sta.push(u);
for(i=head1[u];i!=-;i=edge[i].next){
int v=edge[i].v;
if(v==fa && flag){
flag=;
continue;
}
if(dfn[v]==){
tarjan(v,u);
low[u]=min(low[u],low[v]);
}
else
low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]){
scc++;
while(){
int tem=sta.top();
sta.pop();
belong[tem]=scc;
if(tem==u)break;
}
}
}
int main(){
int i,n,m;
int u,v,w;
while(scanf("%d %d",&n,&m)==){
init(n);
for(i=;i<=m;i++){
scanf("%d %d %d",&u,&v,&w);
addedge(u,v,w,head1);
}
for(i=;i<=n;i++)
if(dfn[i]==)
tarjan(,);
if(scc==){
printf("-1\n");
continue;
}
int last=cnt,whi;
Min=inf;
for(i=;i<last;i+=){
if(belong[edge[i].v]!=belong[edge[i^].v]){
addedge(belong[edge[i].v],belong[edge[i^].v],edge[i].w,head2);
if(edge[i].w<Min){
whi=i;
Min=edge[i].w;
}
}
}
Min=inf;
DP(belong[edge[whi].v],belong[edge[whi^].v]);
DP(belong[edge[whi^].v],belong[edge[whi].v]);
if(Min==inf)printf("-1\n");
else printf("%d\n",Min);
}
return ;
}

hdu 4005 双联通 2011大连赛区网络赛E *****的更多相关文章

  1. HDU 5875 Function -2016 ICPC 大连赛区网络赛

    题目链接 网络赛的水实在太深,这场居然没出线zzz,差了一点点,看到这道题的的时候就剩半个小时了.上面是官方的题意题解,打完了才知道暴力就可以过,暴力我们当时是想出来了的,如果稍稍再优化一下估计就过了 ...

  2. hdu 4006 优先队列 2011大连赛区网络赛F **

    签到题都要想一会 #include<cstdio> #include<iostream> #include<algorithm> #include<cstri ...

  3. hdu 4004 二分 2011大连赛区网络赛D

    题意:一个长为L的河,中间有n个石子,小青蛙需要跳少于m次过河,判断小青蛙每次跳跃最大距离的最小值 最大值最小,用二分 Sample Input 6 1 2 2 25 3 3 11 2 18 Samp ...

  4. hdu 4003 树形dp+分组背包 2011大连赛区网络赛C

    题意:求K个机器人从同一点出发,遍历所有点所需的最小花费 链接:点我 Sample Input 3 1 1 //3个点,从1出发,1个机器人 1 2 1 1 3 1 3 1 2 1 2 1 1 3 1 ...

  5. hdu 4002 欧拉函数 2011大连赛区网络赛B

    题意:求1-n内最大的x/phi(x) 通式:φ(x)=x*(1-1/p1)*(1-1/p2)*(1-1/p3)*(1-1/p4)…..(1-1/pn),其中p1, p2……pn为x的所有质因数,x是 ...

  6. hdu 4001 dp 2011大连赛区网络赛A

    题意:给一些指定长宽高的砖,求能累出的最大高度,不同砖有不同编号,每种编号对下面的砖做出了限制 dp 注意输出要用%I64d,否则会wa,以后不用%lld了 Sample Input 3 10 10 ...

  7. HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛)

    HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛) Panda Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: ...

  8. hdu 4035 2011成都赛区网络赛E 概率dp ****

    太吊了,反正我不会 /* HDU 4035 dp求期望的题. 题意: 有n个房间,由n-1条隧道连通起来,实际上就形成了一棵树, 从结点1出发,开始走,在每个结点i都有3种可能: 1.被杀死,回到结点 ...

  9. hdu 4044 2011北京赛区网络赛E 树形dp ****

    专题训练 #include<stdio.h> #include<iostream> #include<string.h> #include<algorithm ...

随机推荐

  1. 修改更新源sources.list,提高软件下载安装速度(提供Kali 2.0 更新源)

    1.切换到root用户(如果已经是root用户就直接看第二步) dnt@HackerKali:~$ su 密码: 2.用文本编辑器打开sources.list,手动添加下面的更新源 root@Hack ...

  2. squid 学习笔记

    Squid学习笔记 1.安装前的配置 编译安装之前需要校正的参数主要包括File Descriptor和Mbuf Clusters. 1.File Descriptor 查看文件描述符的限制数目: u ...

  3. ETHERNET数据包格式( IP & UDP & ICMP & ARP )

    ETHERNET数据包格式( IP & UDP & ICMP & ARP ) ETHERNET数据包格式 一.ETHERNET 数据包的协议类型 TYPE 的值为 0x0800 ...

  4. 修改linux最大文件句柄数

    大家知道在linux服务器大并发调优时,往往需要预先调优linux参数,其中修改linux最大文件句柄数是最常修改的参数之一. 在linux中执行ulimit -a 即可查询linux相关的参数,如下 ...

  5. thinkphp 3.23 第三方登录sdk集成包

    本集成包在官方包上扩展了支付宝登录和微信,支持最新的3.23版本 config    /* URL配置 */     'URL_CASE_INSENSITIVE' => true, //默认fa ...

  6. Hadoop之 hdfs 系统

    一.NameNode维护着2张表: 1.文件系统的目录结构,以及元数据信息 2.文件与数据块列表的对应关系 存放在fsimage中,在运行的时候加载到内存中的. 操作日志写到edits中   二.Da ...

  7. (源码)自己写的ScrollView里套漂亮的圆角listview(算是漂亮吧。。。)

    找了相关的资料终于写完了: http://blog.csdn.net/jamin0107/article/details/6973845 和 http://emmet1988.iteye.com/bl ...

  8. 关于 CAS 不能登录的问题

    经过排查,是因为 Capistrano 部署中设置了 http_proxy.此时通过 cas.m.xxxx.com 域名去访问 CAS 服务时,就不通了,需要修改为 IP 来访问. 但是公司的 CAS ...

  9. Proc 和 代码块

    文章是从个人博客 搬过来的,大家也可以直接访问我的个人博客哦http://www.iwangzheng.com/ 如何将一段代码从对象中取出并将它像对象一样传递.在ruby中,一个Proc是一个包含一 ...

  10. jquery消息提示框

    用于ajax类型提示的,只显示一个. 只是给个思路而已,代码有很多不足. 4个参数,有2个是可选 调用 $.mTip('类型','显示内容',显示时间,回调函数) 类型: 0 为加载 1 为成功 2 ...