HDU5409---CRB and Graph 2015多校 双联通分量缩点
题意:一个联通的无向图, 对于每一条边, 若删除该边后存在两点不可达,则输出这两个点, 如果存在多个则输出第一个点尽可能大,第二个点尽可能小的。 不存在输出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多校 双联通分量缩点的更多相关文章
- POJ3694 Network —— 边双联通分量 + 缩点 + LCA + 并查集
题目链接:https://vjudge.net/problem/POJ-3694 A network administrator manages a large network. The networ ...
- POJ3177 Redundant Paths —— 边双联通分量 + 缩点
题目链接:http://poj.org/problem?id=3177 Redundant Paths Time Limit: 1000MS Memory Limit: 65536K Total ...
- POJ 3694Network(Tarjan边双联通分量 + 缩点 + LCA并查集维护)
[题意]: 有N个结点M条边的图,有Q次操作,每次操作在点x, y之间加一条边,加完E(x, y)后还有几个桥(割边),每次操作会累积,影响下一次操作. [思路]: 先用Tarjan求出一开始总的桥的 ...
- 边双联通分量缩点+树的直径——cf1000E
题意理解了就很好做 题意:给一张无向图,任意取两个点s,t,s->t的路径上必经边数量为k 求这样的s,t,使得k最大 #include<bits/stdc++.h> #define ...
- 【UVA10972】RevolC FaeLoN (求边双联通分量)
题意: 给你一个无向图,要求把所有无向边改成有向边,并且添加最少的有向边,使得新的有向图强联通. 分析: 这题的解法还是很好想的.先用边双联通分量缩点,然后找新图中入度为0和为1的点,入度为0则ans ...
- 洛谷P2860 [USACO06JAN]冗余路径Redundant Paths(tarjan求边双联通分量)
题目描述 In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numbered 1. ...
- Spoj 2878 KNIGHTS - Knights of the Round Table | 双联通分量 二分图判定
题目链接 考虑建立原图的补图,即如果两个骑士不互相憎恨,就在他们之间连一条无向边. 显而易见的是,如果若干个骑士在同一个点数为奇数的环上时,他们就可以在一起开会.换句话说,如果一个骑士被一个奇环包含, ...
- hihocoder #1190 : 连通性·四 点双联通分量
http://hihocoder.com/problemset/problem/1190?sid=1051696 先抄袭一下 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描 ...
- lightoj 1300 边双联通分量+交叉染色求奇圈
题目链接:http://lightoj.com/volume_showproblem.php?problem=1300 边双连通分量首先dfs找出桥并标记,然后dfs交叉着色找奇圈上的点.这题只要求在 ...
随机推荐
- ASPNET5应用程序启动
1. 启动类 在asp.net5当中,Startup类提供应用程序的入口,对所有应用程序是必须的.争对特定环境的配置的starup class和方法也是有可能的, 但是,不管怎样, 一个Startup ...
- 通过ip地址获取当前地理位置
1. 使用接口的方式: 这种方式是相对稳定,而且提供的数据相对稳定,提供接口的地方很多,大家可以参照 http://www.hujuntao.com/api/the-ip-address-api-a ...
- asp.net使用dorpdownlist绑定无限级分类
/// <summary> /// 绑定父项分类 /// </summary> protected void DDLBindClass( ...
- Android开发手记(20) 数据存储五 网络存储
Android为数据存储提供了五种方式: 1.SharedPreferences 2.文件存储 3.SQLite数据库 4.ContentProvider 5.网络存储 安卓的网络存储比较简单,因为A ...
- iOS开发中常用的宏
前言 今天将一些简化工程代码的宏定义拿出来分享一下,自定义一些宏可以有效的简化代码,提高编码效率. Application #define APPLICATION [UIApplication sha ...
- Swift - 31 - 常量参数, 变量参数和inout参数
//: Playground - noun: a place where people can play import UIKit // swift中默认情况下, 传入的参数是不可以修改的, 也就是l ...
- linux变量心得
前一段时间学习了一下linux的变量,现在总结有3点需要特别注意: linux变量和C/C++变量的区别 linux变量的引用 linux变量特有的命令替换 先说第一点,linux变量更像是宏定义,只 ...
- cal命令详解与练习
cal: 显示日历. 命令格式: cal [-smjy13] [[[day] month] year] 参数说明 -1 显示当前月日历 -3 显示当前月前后3月的日历 -s 以星期天为第一天显示 -m ...
- 141 Linked List Cycle(判断链表是否有环Medium)
题目意思:链表有环,返回true,否则返回false 思路:两个指针,一快一慢,能相遇则有环,为空了没环 ps:很多链表的题目:都可以采用这种思路 /** * Definition for singl ...
- ggts下载地址
地址:http://spring.io/tools/ggts See All Versions可以下载更多版本,里面包含安装版和解压版