<题目链接>

题目大意:

  给你一个连通的无向图,问你删除每一条边后,是否能够出现一对(u,v),使得u,v不连通,且u<v,如果有多对u,v,则输出尽量大的u,和尽量小的v。

解题分析:
  首先要明确,因为该图是连通的无向图,所以删除的边是桥才能够使至少两点不连通。但是对于删除桥的情况,如何输出尽可能大的u和尽可能小的v呢?

  我们要知道,删除一个桥,是将整张图分成两部分,这两部分的点仍然是连通的,并且,由于题目要求u<v,且u尽可能的大,v尽可能的小,所以,我们可以推断出,u与n一定不在同一部分,并且u是它所属部分的最大值,同时由于所有点的序号是连续的,u是那一部分的最大值,所以v的值一定是u+1。所以本题的目标就已经很明确了,就是先对每个点双连通分量进行缩点,并且维护每个连通分量的最大值。最后寻找u值得时候,就直接用DFS寻找不含n点的部分的最大值即可。

 #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 1e5+;
#define clr(a,b) memset(a,b,sizeof(a))
struct Edge{
int to,next;
bool vis,bridge;
Edge(){}
Edge(int _to,int _next):to(_to),next(_next){vis=false;bridge=false;}
}e[MAXN<<];
int times,n,m,top,bcc,tot;
int dfn[MAXN],low[MAXN],pre[MAXN],head[MAXN],stk[MAXN],belong[MAXN],res[MAXN];
void init(){
top=times=bcc=tot=;
clr(head,-);clr(dfn,);clr(low,);clr(belong,);clr(pre,);
}
void addedge(int u,int v){
e[tot]=Edge(v,head[u]);head[u]=tot++;
e[tot]=Edge(u,head[v]);head[v]=tot++;
}
void Tarjan(int u){
dfn[u]=low[u]=++times;
stk[++top]=u;
for(int i=head[u];i!=-;i=e[i].next){
int v=e[i].to;
if(e[i].vis)continue;
e[i].vis=e[i^].vis=true; //将正反边全部标记
if(!dfn[v]){
pre[v]=u; //记录下父亲节点
Tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(!belong[v])low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]){
bcc++;
res[bcc]=-; //进行初始化
belong[u]=bcc;
while(true){
int v = stk[top--];
belong[v]=bcc;
res[bcc]=max(res[bcc],v); //维护连通分量中的最大值
if(v==u)break;
}
}
}
Edge edg[MAXN*];
int dep[MAXN],val[MAXN],head1[MAXN],tot1;
void init1(){
tot1=;
clr(head1,-);clr(dep,);
}
void AddEdge(int u,int v){
edg[tot1]=Edge(v,head1[u]);head1[u]=tot1++;
edg[tot1]=Edge(u,head1[v]);head1[v]=tot1++;
}
void dfs(int u,int d){ //得到以u为根的子树中编号最大的节点,并且得到每个节点的深度
dep[u]=d;
val[u]=res[u];
for(int i=head1[u];~i;i=edg[i].next){
int v=edg[i].to;
if(!dep[v]){
dfs(v,d+);
val[u]=max(val[u],val[v]); //val[u]为以u为根的子树中最大的编号
}
}
}
void solve(){
Tarjan();
for(int i=;i<tot;i++){ //遍历所有的边
if(e[i].bridge)continue;
int u=e[i].to,v=e[i^].to;
if(pre[v]==u&&dfn[u]<low[v]){ //如果u为v的父亲,且dfn[u]<low[v],说明u、v之间为桥
e[i].bridge=e[i^].bridge=true; //标记该边是否为桥
}
}
init1(); //为缩点后重新构图进行初始化
for(int i=;i<tot;i+=){
int u=e[i].to,v=e[i^].to;
if(belong[u]!=belong[v]){
AddEdge(belong[u],belong[v]); //缩点后进行重新构图
}
}
dfs(belong[n],); //以包含n的点双连通分量为树根
for(int i=;i<tot;i+=){
int u=e[i].to,v=e[i^].to;
if(e[i].bridge){ //因为肯定是两边中深度更浅的节点为根的子树中包含n节点,所以直接输出以深度更深的节点为根的最大值和这个最大值+1(这个最大值相当于是u,因为v>u,并且v要最小所以v为u+1)
if(dep[belong[u]]>dep[belong[v]])printf("%d %d\n",val[belong[u]],val[belong[u]]+);
else printf("%d %d\n",val[belong[v]],val[belong[v]]+);
}
else printf("0 0\n"); //如果不是桥,则输出0 0
}
}
int main(){
int T;scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
init();
for(int i=,x,y;i<m;i++){
scanf("%d%d",&x,&y);
addedge(x,y);
}
solve();
}
return ;
}

2018-12-04

HDU 5409 CRB and Graph 【点双连通+DFS】的更多相关文章

  1. hdu 5409 CRB and Graph(边双联通分量)

    题意: 给一个图一些边,保证图连通 问对于每条边,如果去除该边后使得图中一些点不连通.设这些点(u,v),要求使u尽量小,v尽量大,输出这样的(u,v).否则输出0 0. #include <b ...

  2. HDOJ 5409 CRB and Graph 无向图缩块

    无向图缩块后,以n所在的块为根节点,dp找每块中的最大值. 对于每一个桥的答案为两块中的较小的最大值和较小的最大值加1 CRB and Graph Time Limit: 8000/4000 MS ( ...

  3. 【HDU5409】CRB and Graph 边双联通 子树最值

    HDU # 题意 有一个简单图,n个点,m条边.对于每条割边,求出删去这条边后,在两个联通块中各取一个u,v.使得u<v,并且u尽量大而v尽量小. # 思路 求出边双联通是肯定的. 答案的限制条 ...

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

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

  5. HDU 5416 CRB and Tree(前缀思想+DFS)

    CRB and Tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Tot ...

  6. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  7. HDU 3849 By Recognizing These Guys, We Find Social Networks Useful(双连通)

    HDU 3849 By Recognizing These Guys, We Find Social Networks Useful pid=3849" target="_blan ...

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

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

  9. hdu 4612 Warm up 双连通缩点+树的直径

    首先双连通缩点建立新图(顺带求原图的总的桥数,事实上因为原图是一个强连通图,所以桥就等于缩点后的边) 此时得到的图类似树结构,对于新图求一次直径,也就是最长链. 我们新建的边就一定是连接这条最长链的首 ...

随机推荐

  1. Confluence 6 配置 Office 连接器选项

    具有系统管理员权限的用户可以配置 Office 连接器的属性和相关表现. 希望设置 Office 连接器的配置属性: 进入  > 基本配置(General Configuration) > ...

  2. Confluence 6 连接到 Jira 用户管理的限制

    当你在使用 JIRA 目录为用户目录的时候,请考虑下面的一些限制和建议. 不知道跨平台的多应用单点登录 当你使用 JIRA 为你的目录管理器的时候,系统将不能支持跨平台的单点登录.当 JIRA 用作目 ...

  3. Metasploit 使用后门和Rootkit维持访问

    1.内存攻击指的是攻击者利用软件的漏洞,构造恶意的输入导致软件在处理输入数据时出现非预期的错误,将输入数据写入内存中的某些敏感位置,从而劫持软件控制流,转而执行外部的指令代码,造成目标系统获取远程控制 ...

  4. this作用范围

    1. this的指向 var name='window';var obj={ name:'obj', say:function(){ return function(){ return this.na ...

  5. cf862d 交互式二分

    /* 二分搜索出一个01段或10即可 先用n个0确定1的个数num 然后测试区间[l,mid]是否全是0或全是1 如果是,则l=mid,否则r=mid,直到l+1==r 然后再测试l是1还是r是1 如 ...

  6. bzoj 1222

    比较简单的背包dp,设计状态f[i][j]表示到了前i个物品,第一台机器加工时间为j,第二台机器加工所用的最小时间,然后背包转移即可 本题卡空间,需要滚动数组优化 本题卡时间,稍微卡下常就行 #inc ...

  7. typeof操作符--undefined与null

    <!DOCTYPE html><html><head> <meta charset="utf-8"> <title>ty ...

  8. 安装Mysql5.6.19

    存在异常: ERROR (HY000): Can't connect to MySQL server on 'localhost' (10061) 原因:Mysql的服务没有启动 windows7启动 ...

  9. 集腋成裘-05-angularJS -初识angular

    私以为angular的最大特点是:只关注数据 1.1 angular之:双向绑定 <!DOCTYPE html> <html ng-app=""> < ...

  10. java Map按Key排序

    public static void main(String[] args) { Map<String, String> map = new TreeMap<String, Stri ...