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. Python(简单图形和文件处理)编程

    Python确实是一门很简洁而且功能有强大的语言,我觉得开始学习很容易理解,说到熟练和精通还是不容易的,还需不断学习. 从最基础的语法学习,有些部分各种语言是相同的,让人很好理解.编程也是从最简单语法 ...

  2. IDEA:No SLF4J providers were found.

    如果您是用IDEA 的 maven 写的 将slf4j的导入包 更改 为下列代码 <dependency> <groupId>org.slf4j</groupId> ...

  3. 【Android Studio】常用快捷键

    1. 删除一行:Ctrl + X 更新中……

  4. codeforces 339 D.Xenia and Bit Operations(线段树)

    这个题目属于线段树的点更新区间查询,而且查的是整个区间,其实不用写query()函数,只需要输出根节点保存的值就可以了. 题意: 输入n,m表示有2^n个数和m个更新,每次更新只把p位置的值改成b,然 ...

  5. jenkins弱口令漏洞

    jenkins弱口令漏洞 一.漏洞描述 通过暴力破解管理控制台,如果爆破成功,可获得后台管理权限.操作后台,后台可通过脚本命令行功能执行系统命令,如反弹shell等,低权限可以通过创建控制台输出方式执 ...

  6. 给最近正在找工作(iOS)的朋友一些建议/经验

    众所周知, iOS开发找工作越来越难, 企业要求越来越高,一方面是资本寒冬期+七八月是企业招人淡季, 另外一方面也是iOS市场饱和.最近有出去看新机会, 所以下面记录一下面试XimalayaFM的大概 ...

  7. 简洁明了的Noip考场策略 / 平时做题也适用

    1.选择策略: 评估的标准得分的难度不是AC的难度 2.思考问题: 怀疑的眼光审视自己 3.写代码前: 想想可不可以换一种代码实现会好写很多 把自己的思路再理一遍,可以写到纸上,记下来大致关键顺序 4 ...

  8. ext container的使用的场景

    container 是 panel 简化,他称之为容器,而panel则是面板. 如果不需要类似Ext.panel.Panel,Ext.window.Window和Ext.tab.Panel 等功能,则 ...

  9. Appium+python自动化(二十九)- 模拟手指在手机上多线多点作战 - 多点触控(超详解)

    简介 在网页中我们经常使用缩放操作来便利的查看具体的信息,在appium中使用MultiAction多点触控的类来实现.MultiAction是多点触控的类,可以模拟用户多点操作.主要包含加载add( ...

  10. 【错误】【vscode】输出中文是乱码问题