HDU

# 题意

有一个简单图,n个点,m条边。对于每条割边,求出删去这条边后,在两个联通块中各取一个u,v。使得u<v,并且u尽量大而v尽量小。

# 思路

求出边双联通是肯定的。

答案的限制条件是重点。

假设分出来的两个联通块,一个的最大值是mx1,另一个的最大值是mx2。那么u = min(mx1, mx2),因为取个小点的,才能在另一个联通块中找到对应的v。

显然mx1,mx2中一个值等于n,所以我们只用找不包含n的联通块中的最大值。

怎么找,可以令n为根结点,dfs子树的最大值就行了。

又由于v越小越好,我们可以直接令v = u + 1;

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl;
#define FOR(a, b, c) for(int a = b; a <= c; ++ a) typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll; template<class T> void _R(T &x) { cin >> x; }
void _R(int &x) { scanf("%d", &x); }
void _R(ll &x) { scanf("%lld", &x); }
void _R(double &x) { scanf("%lf", &x); }
void _R(char &x) { scanf(" %c", &x); }
void _R(char *x) { scanf("%s", x); }
void R() {}
template<class T, class... U> void R(T &head, U &... tail) { _R(head); R(tail...); } template<typename T>
inline T read(T&x){
x=;int f=;char ch=getchar();
while (ch<''||ch>'') f|=(ch=='-'),ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x=f?-x:x;
} const int inf = 0x3f3f3f3f; const int mod = 1e9+; /**********showtime************/
const int maxn = 1e5+;
vector<pii>mp[maxn];
set <pii>nmp[maxn];
int dfn[maxn],low[maxn],belong[maxn],tim;
int scc_cnt;
int ans[maxn];
int a[maxn], dp[maxn];
stack<int>st;
void dfs(int u, int fa) {
dfn[u] = low[u] = ++tim;
st.push(u);
for(pii p : mp[u]){
int v = p.fi;
if(v == fa) continue;
if(!dfn[v]) dfs(v, u);
if(!belong[v]) low[u] = min(low[u], low[v]);
}
if(low[u] == dfn[u]) {
scc_cnt++;
nmp[scc_cnt].clear();
int now;
while(true){
now = st.top(); st.pop();
belong[now] = scc_cnt;
a[scc_cnt] = max(a[scc_cnt], now);
if(now == u) break;
}
}
} void cal(int u, int fa) {
dp[u] = a[u];
for(pii p : nmp[u]) {
int v = p.fi, id = p.se;
if(v == fa) continue;
cal(v, u);
ans[id] = dp[v];
dp[u] = max(dp[u], dp[v]);
}
}
int main(){
int T; scanf("%d", &T);
while(T--) {
int n,m;
scanf("%d%d", &n, &m);
for(int i=; i<=n; i++) mp[i].clear(), dfn[i] = ,dp[i] = , a[i] = ,belong[i] = ;
for(int i=; i<=m; i++) {
int u,v;
scanf("%d%d", &u, &v);
mp[u].pb(pii(v, i));
mp[v].pb(pii(u, i));
ans[i] = ;
}
tim = ;
scc_cnt = ;
for(int i=; i<=n; i++) if(!dfn[i]) dfs(i, i);
for(int u=; u<=n; u++) {
for(pii p : mp[u]) {
int v = p.fi;
if(belong[u] == belong[v]) continue;
nmp[belong[u]].insert(pii(belong[v], p.se));
}
}
cal(belong[n], belong[n]); for(int i=; i<=m; i++) printf("%d %d\n", ans[i], ans[i] + (ans[i] != ));
}
return ;
}

【HDU5409】CRB and Graph 边双联通 子树最值的更多相关文章

  1. HDU5409---CRB and Graph 2015多校 双联通分量缩点

    题意:一个联通的无向图, 对于每一条边, 若删除该边后存在两点不可达,则输出这两个点, 如果存在多个则输出第一个点尽可能大,第二个点尽可能小的. 不存在输出0 0 首先 若删除某一条边后存在多个联通分 ...

  2. Tarjan总结(缩点+割点(边)+双联通+LCA+相关模板)

    Tarjan求强连通分量 先来一波定义 强连通:有向图中A点可以到达B点,B点可以到达A点,则称为强连通 强连通分量:有向图的一个子图中,任意两个点可以相互到达,则称当前子图为图的强连通分量 强连通图 ...

  3. hihocoder #1190 : 连通性·四 点双联通分量

    http://hihocoder.com/problemset/problem/1190?sid=1051696 先抄袭一下 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描 ...

  4. 图连通性【tarjan点双连通分量、边双联通分量】【无向图】

    根据 李煜东大牛:图连通性若干拓展问题探讨 ppt学习. 有割点不一定有割边,有割边不一定有割点. 理解low[u]的定义很重要. 1.无向图求割点.点双联通分量: 如果对一条边(x,y),如果low ...

  5. poj 3177 Redundant Paths 求最少添加几条边成为双联通图: tarjan O(E)

    /** problem: http://poj.org/problem?id=3177 tarjan blog: https://blog.csdn.net/reverie_mjp/article/d ...

  6. POJ3177 & 求边双联通分量

    题意: 给一张无向图,求加多少边使原图任意两点边双联通. SOL: 一个不会写边双点双强联通的傻逼. 一个结论:把一棵树变成满足条件的图需要加的边使入度为1的点数+1除以2.------>就是树 ...

  7. [POJ3177]Redundant Paths(双联通)

    在看了春晚小彩旗的E技能(旋转)后就一直在lol……额抽点时间撸一题吧…… Redundant Paths Time Limit: 1000MS   Memory Limit: 65536K Tota ...

  8. hdu 3849 (双联通求桥)

    一道简单的双联通求桥的题目,,数据时字符串,,map用的不熟练啊,,,,,,,,,,,,, #include <iostream> #include <cstring> #in ...

  9. hdu 4612 (双联通+树形DP)

    加一条边后最少还有多少个桥,先Tarjan双联通缩点, 然后建树,求出树的直径,在直径起点终点加一条边去的桥最多, #pragma comment(linker, "/STACK:10240 ...

随机推荐

  1. JS中构造函数和普通函数有什么区别

    JS中构造函数有普通函数有什么区别? 1.一般规则 构造函数都应该以 一个大写字母开头,eg: function Person(){...} 而非构造函数则应该以一个小写字母开头,eg: functi ...

  2. Linux内容点(部分)

    文件属性 -w      文件或目录,对目前(有效的)用户或组来说是可写的       -x       文件或目录,对目前(有效的)用户或组来说是可执行的       -o       文件或目录, ...

  3. UIRefreshControl 问题

    这两天在学UIRefreshControl,主要参照的是github上的一个Demo(网址 https://github.com/evgeniymikholap/UIRefreshControlExa ...

  4. Java 求字符串中出现频率最高字符

    前段时间接触的这个题目,大体理解了,还有些小地方仍待进一步品味,暂且记下. import java.util.ArrayList; import java.util.Arrays; import ja ...

  5. java的properties文件从数据库添加到文件

    package com.xian.jdbc; import java.io.BufferedInputStream; import java.io.FileInputStream; import ja ...

  6. 从源码看java线程状态

    关于java线程状态,网上查资料很混乱,有的说5种状态,有的说6种状态,初学者搞不清楚这个线程状态到底是怎么样的,今天我讲一下如何看源码去解决这个疑惑. 直接上代码: public class Thr ...

  7. GStreamer流媒体知识介绍

    GStreamer框架 1.GStreamer是什么? 众所周知,Microsoft's Windows和Apple's MacOS对多媒体设备.多媒体创作.播放和实时处理等方面都有很好的支持,而Li ...

  8. 4如何用PHP给MySQL数据库添加记录

    首先连接数据库(依旧用第二篇的方法) 假设数据库表里只有id,name,email三列 添加以下代码 $inputemail=写你要的email;$inputname=写你要的name;//先设定你要 ...

  9. LeetCode :2.两数相加 解题报告及算法优化思路

    题目连接:2.两数相加 题意 题目难度标为 中等, 因为题意上有一部分理解难度,以及需要数据结构的链表基础. 还不知道到链表的童鞋可以粗略的看下百度百科或者是翻出数据结构的书看一看,通俗一点的语言来解 ...

  10. [转载]MongoDB管理基础

    1.  启动和停止MongoDB: 执行mongod命令启动MongoDB服务器.mongod有很多可配置的选项,我们通过mongod --help可以查看所有选项,这里仅介绍一些主要选项:    - ...