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

首先 若删除某一条边后存在多个联通分量则该边一定是桥, 那么我们可以先处理出所有的桥,然后把所有双联通分量缩点,缩点之后就变成了一棵树。

而树上的每一条边都是一个桥, 考虑每条边的输出,删除某一边后肯定会出现两个联通分量, 需要记录两个联通分量中最大的点max1 max2, 如果max1!=n 则答案就是max1 max1+1否则max2 max2+1

现在的问题就转化为了如何求 不包含n的联通分量的最大值,因为两个联通分量肯定有一个联通分量的最大值为n, 所以 我们可以从包含n这个点的联通分量开始DFS, 每次遍历后更新一下,此时子树的最大值就是答案。

orz,第一次学习双联通分量。

 #include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + ;
typedef pair <int, int>pii;
vector<pii>G[MAXN];
bool isBridge[MAXN];
int clk, pre[MAXN], low[MAXN];
int IDX, maxv[MAXN], newIdx[MAXN], newMax[MAXN];
int U[MAXN], V[MAXN];
int ans[MAXN];
bool vis[MAXN];
int n, m;
void init () {
memset(isBridge, false, sizeof (isBridge));
memset(pre, , sizeof (pre));
memset(low, , sizeof (low));
clk = ;
for (int i = ; i < MAXN; i++) {
G[i].clear();
}
}
void DFS (int u, int pa) {
int lowu = pre[u] = ++clk;
for (int i = ; i < G[u].size(); i++) {
pii e = G[u][i];
int v = e.first;
int idx = e.second;
if (!pre[v]) {
DFS(v, u);
lowu = min(lowu, low[v]);
if (low[v] > pre[u]) {
isBridge[idx] = true;
}
} else if (pre[v] < pre[u] && v != pa) {
lowu = min(lowu, pre[v]);
}
}
low[u] = lowu;
}
void DFS2(int u, int pa) {
vis[u] = true;
maxv[u] = u;
newIdx[u] = IDX;
for (int i = ; i < G[u].size(); i++) {
pii e = G[u][i];
int v = e.first;
int idx = e.second;
if (!isBridge[idx] && v != pa && !vis[v]) {
DFS2(v, u);
maxv[u] = max(maxv[u], maxv[v]);
}
}
}
void BCC_Bridge() {
DFS(, -);
memset(vis, false, sizeof (vis));
IDX = ;
for (int i = ; i <= n; i++) {
if (!vis[i]) {
IDX++;
DFS2(i, -);
}
}
for (int i = ; i <= n; i++) {
G[i].clear();
}
for (int i = ; i < m; i++) {
if (isBridge[i]) {
int u = newIdx[U[i]], v = newIdx[V[i]];
G[u].push_back(make_pair(v, i));
G[v].push_back(make_pair(u, i));
}
}
}
void solve (int u, int pa) {
pre[u] = ++clk;
ans[u] = newMax[u];
for (int i = ; i < G[u].size(); i++) {
int v = G[u][i].first;
if (v != pa) {
solve(v, u);
ans[u] = max(ans[u], ans[v]);
} }
}
int main() {
int T;
scanf ("%d", &T);
while (T--) {
init();
scanf ("%d%d", &n, &m);
for (int i = ; i < m; i++) {
int u, v;
scanf ("%d%d", &u, &v);
U[i] = u, V[i] = v;
G[u].push_back(make_pair(v, i));
G[v].push_back(make_pair(u, i));
}
BCC_Bridge();
for (int i = ; i <= n; i++) {
newMax[newIdx[i]] = maxv[i];
}
int u;
for (u = ; u <= n; u++) {
if (newMax[u] == n) {
break;
}
}
memset(pre, , sizeof pre);
clk = ;
solve (u, );
for (int i = ; i < m; i++) {
int u = newIdx[U[i]], v = newIdx[V[i]];
if (u == v) {
printf("0 0\n");
} else {
if (pre[u] < pre[v]) {
swap(u, v);
}
printf("%d %d\n", ans[u], ans[u]+);
}
}
}
return ;
}

HDU5409---CRB and Graph 2015多校 双联通分量缩点的更多相关文章

  1. POJ3694 Network —— 边双联通分量 + 缩点 + LCA + 并查集

    题目链接:https://vjudge.net/problem/POJ-3694 A network administrator manages a large network. The networ ...

  2. POJ3177 Redundant Paths —— 边双联通分量 + 缩点

    题目链接:http://poj.org/problem?id=3177 Redundant Paths Time Limit: 1000MS   Memory Limit: 65536K Total ...

  3. POJ 3694Network(Tarjan边双联通分量 + 缩点 + LCA并查集维护)

    [题意]: 有N个结点M条边的图,有Q次操作,每次操作在点x, y之间加一条边,加完E(x, y)后还有几个桥(割边),每次操作会累积,影响下一次操作. [思路]: 先用Tarjan求出一开始总的桥的 ...

  4. 边双联通分量缩点+树的直径——cf1000E

    题意理解了就很好做 题意:给一张无向图,任意取两个点s,t,s->t的路径上必经边数量为k 求这样的s,t,使得k最大 #include<bits/stdc++.h> #define ...

  5. 【UVA10972】RevolC FaeLoN (求边双联通分量)

    题意: 给你一个无向图,要求把所有无向边改成有向边,并且添加最少的有向边,使得新的有向图强联通. 分析: 这题的解法还是很好想的.先用边双联通分量缩点,然后找新图中入度为0和为1的点,入度为0则ans ...

  6. 洛谷P2860 [USACO06JAN]冗余路径Redundant Paths(tarjan求边双联通分量)

    题目描述 In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numbered 1. ...

  7. Spoj 2878 KNIGHTS - Knights of the Round Table | 双联通分量 二分图判定

    题目链接 考虑建立原图的补图,即如果两个骑士不互相憎恨,就在他们之间连一条无向边. 显而易见的是,如果若干个骑士在同一个点数为奇数的环上时,他们就可以在一起开会.换句话说,如果一个骑士被一个奇环包含, ...

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

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

  9. lightoj 1300 边双联通分量+交叉染色求奇圈

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1300 边双连通分量首先dfs找出桥并标记,然后dfs交叉着色找奇圈上的点.这题只要求在 ...

随机推荐

  1. Delpoyment assembly

    遇见异常: java.lang.ClassNotFoundException: 原因:没有对tomcat进行依赖说明 解决: properties - Delpoyment assembly 将tom ...

  2. C#解leetcode 18. 4Sum

    Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = tar ...

  3. Angular JS API

    ng function angular.bind angular.bootstrap angular.copy angular.element angular.equals angular.exten ...

  4. 登录模块需要用到session留底

    <% HttpSession sessions=request.getSession(); Object sessionValues=sessions.getAttribute("ui ...

  5. 关于timestamp的二三事

    之所以要写timestamp的随笔,是因为之前对它的理解存在误区,so. I have to remind myself by writing this informal essay. 微软文档链接: ...

  6. 用java写bp神经网络(一)

    根据前篇博文<神经网络之后向传播算法>,现在用java实现一个bp神经网络.矩阵运算采用jblas库,然后逐渐增加功能,支持并行计算,然后支持输入向量调整,最后支持L-BFGS学习算法. ...

  7. PHP MySQL 插入多条数据

    PHP MySQL 插入多条数据 使用 MySQLi 和 PDO 向 MySQL 插入多条数据 mysqli_multi_query() 函数可用来执行多条SQL语句. 以下实例向 "MyG ...

  8. 通过Unity依赖注入

    前言 Unity容器的思想起始于我在为Web Client Sofitware Factory项目工作的时候,微软的patterns&practices团队已经使用依赖注入的概念好几年了在那时 ...

  9. QT实现单个EXE文件

    有时候发布用Qt写的软件是件令人烦恼的事情,明明发布的只是一个简单功能的小软件,非得再附上一堆超大的动态链接库,实在让人觉得汗颜 . 在可执行文件单文件化方面,有多种方法.常用的是编译并使用静态 Qt ...

  10. 【USACO 3.2.5】魔板

    [描述] 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 我们知道魔板的每一个方格都有一种颜色.这8种颜色用前8个 ...