Bridges Gym - 100712H 无向图的边双连通分量,Tarjan缩点
http://codeforces.com/gym/100712/attachments
题意是给定一个无向图,要求添加一条边,使得最后剩下的桥的数量最小。
注意到在环中加边是无意义的。
那么先把环都缩成一个点,然后重新建立一颗树,找出树的直径就好。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
const int maxn = 1e5 + ;
struct Edge {
int u, v, tonext;
}e[maxn * ], tree[maxn * ];
int first[maxn], num;
int first_tree[maxn], num_tree;
void addEdge(int u, int v) {
++num;
e[num].u = u, e[num].v = v, e[num].tonext = first[u];
first[u] = num;
}
int DFN[maxn], low[maxn], when, st[maxn], top;
int id[maxn], toSelid;
bool vis[maxn];
void tarjan(int cur, int fa) {
DFN[cur] = low[cur] = ++when; //时间戳
st[++top] = cur; //进栈
vis[cur] = true;
for (int i = first[cur]; i; i = e[i].tonext) {
int v = e[i].v;
if (v == fa) continue;
if (!DFN[v]) { //没访问过
tarjan(v, cur);
low[cur] = min(low[cur], low[v]);
} else if (vis[v]) { // 访问过,而且还在栈里
low[cur] = min(low[cur], DFN[v]);
}
}
if (low[cur] == DFN[cur]) { //这个是强连通分量的根节点。
++toSelid;
do {
id[st[top]] = toSelid; //块id
// sum[toSelId]++; //id节点个数
// printf("%d ", st[top]);
vis[st[top]] = false;
top--;
} while (cur != st[top + ]);
// printf("\n");
}
} void solveTarjan(int n) {
memset(DFN, , sizeof DFN);
memset(low, , sizeof low);
memset(vis, , sizeof vis);
when = top = toSelid = ;
for (int i = ; i <= n; ++i) {
if (!DFN[i]) tarjan(i, i);
}
}
void addEdgeTree(int u, int v) {
++num_tree;
tree[num_tree].u = u, tree[num_tree].v = v, tree[num_tree].tonext = first_tree[u];
first_tree[u] = num_tree;
} struct bfsnode {
int cur, cnt;
bfsnode(int _cur, int _cnt) {
cur = _cur;
cnt = _cnt;
}
};
int tree_diameter(int begin, bool flag) {
memset(vis, , sizeof vis);
queue<struct bfsnode> que;
while (!que.empty()) que.pop();
que.push(bfsnode(begin, ));
vis[begin] = true;
int to = begin, mx = ;
while (!que.empty()) {
struct bfsnode t = que.front();
que.pop();
for (int i = first_tree[t.cur]; i; i = tree[i].tonext) {
int v = tree[i].v;
if (vis[v]) continue;
vis[v] = true;
que.push(bfsnode(v, t.cnt + ));
if (mx < t.cnt + ) {
to = v;
mx = t.cnt + ;
}
}
}
if (flag) return mx;
else return to;
} void work() {
memset(first, , sizeof first);
memset(first_tree, , sizeof first_tree);
num = num_tree = ;
int n, m;
scanf("%d%d", &n, &m);
for (int i = ; i <= m; ++i) {
int u, v;
scanf("%d%d", &u, &v);
addEdge(u, v);
addEdge(v, u);
}
solveTarjan(n);
// for (int i = 1; i <= n; ++i) {
// cout << id[i] << " ";
// }
for (int i = ; i <= n; ++i) {
for (int j = first[i]; j; j = e[j].tonext) {
int v = e[j].v;
if (id[i] == id[v]) continue;
addEdgeTree(id[i], id[v]);
addEdgeTree(id[v], id[i]);
}
}
int res = tree_diameter(, );
int di = tree_diameter(res, );
int ans = toSelid - di - ;
ans = max(ans, );
cout << ans << endl;
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
int t;
scanf("%d", &t);
while (t--) work();
return ;
}
Bridges Gym - 100712H 无向图的边双连通分量,Tarjan缩点的更多相关文章
- tarjan算法与无向图的连通性(割点,桥,双连通分量,缩点)
基本概念 给定无向连通图G = (V, E)割点:对于x∈V,从图中删去节点x以及所有与x关联的边之后,G分裂为两个或两个以上不相连的子图,则称x为割点割边(桥)若对于e∈E,从图中删去边e之后,G分 ...
- tarjan算法求无向图的桥、边双连通分量并缩点
// tarjan算法求无向图的桥.边双连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> ...
- 点/边 双连通分量---Tarjan算法
运用Tarjan算法,求解图的点/边双连通分量. 1.点双连通分量[块] 割点可以存在多个块中,每个块包含当前节点u,分量以边的形式输出比较有意义. typedef struct{ //栈结点结构 保 ...
- HDU4612Warm up 边双连通 Tarjan缩点
N planets are connected by M bidirectional channels that allow instant transportation. It's always p ...
- POJ 3352 无向图边双连通分量,缩点,无重边
为什么写这道题还是因为昨天多校的第二题,是道图论,HDU 4612. 当时拿到题目的时候就知道是道模版题,但是苦于图论太弱.模版都太水,居然找不到. 虽然比赛的时候最后水过了,但是那个模版看的还是一知 ...
- 无向图的边双连通分量(EBC)
嗯,首先边双连通分量(双连通分量之一)是:在一个无向图中,去掉任意的一条边都不会改变此图的连通性,即不存在桥(连通两个边双连通分量的边),称作边双连通分量.一个无向图的每一个极大边双连通子图称作此无向 ...
- [HDOJ4612]Warm up(双连通分量,缩点,树直径)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4612 所有图论题都要往树上考虑 题意:给一张图,仅允许添加一条边,问能干掉的最多条桥有多少. 必须解决 ...
- 无向图的点双连通分量(tarjan模板)
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #i ...
- UOJ#30/Codeforces 487E Tourists 点双连通分量,Tarjan,圆方树,树链剖分,线段树
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ30.html 题目传送门 - UOJ#30 题意 uoj写的很简洁.清晰,这里就不抄一遍了. 题解 首先建 ...
随机推荐
- codeforces 450B B. Jzzhu and Sequences(矩阵快速幂)
题目链接: B. Jzzhu and Sequences time limit per test 1 second memory limit per test 256 megabytes input ...
- 创建calico网络报错client response is invalid json
使用docker创建calico网络失败. # docker network create --driver calico --ipam-driver calico-ipam testcalico E ...
- Nhibernate中多Or条件的查询,很多Or的查询
public IList<object[]> GetRequestAllByUserCodeUnitSysClassify1(string unitNo, string system, s ...
- web面试常见问题补充
jquery Ajax $ajax({ Url:”test.html”,-----发送请求的地址 Async:true;------异步操作 Cache:true,-----可以从缓冲中加载 Type ...
- 性能测试之Jmeter学习(二)
一.Jmeter的基本操作 1.添加|移除测试元件 2.加载和保存测试元件 3.配置测试对中的测试元件 4.保存测试计划 5.运行测试计划 6.终止测试 7.错误报告 二.Jmeter体系结构 注释: ...
- 理解复杂的const和typedef和指针的关系
// container.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #inclu ...
- AJAX提交到Handler.ashx一般处理程序返回json数据-转
直接贴代码!我也测试通过! 一切看注释! 谢谢! <%@ WebHandler Language="C#" class="Handler" %> u ...
- ASP.NET学习笔记(一)相关概念
ASP.NET 是一个开发框架,用于通过 HTML.CSS.JavaScript 以及服务器脚本来构建网页和网站. ASP.NET 支持三种开发模式: Web Pages MVC Web Forms ...
- fitnesse(gradle构建)安装步骤
1.安装jdk.ant.gradle(参考http://www.cnblogs.com/274914765qq/p/4401525.html) 2.下载Fitnesse https://github. ...
- 使用ant时 出现 java.lang.OutOfMemoryErro r: Java heap space的解决办法
在Linux的shell中,使用export设置ANT_OPTS变量,值为1G export ANT_OPTS=-Xmx1g ant 同理在windows的cmd中,使用set设置ANT_OPTS变量 ...