【HDOJ4612】【双连通分量缩点+找树的直径】
http://acm.hdu.edu.cn/showproblem.php?pid=4612
Warm up
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 8309 Accepted Submission(s): 1905
If we can isolate some planets from others by breaking only one channel , the channel is called a bridge of the transportation system.
People don't like to be isolated. So they ask what's the minimal number of bridges they can have if they decide to build a new channel.
Note that there could be more than one channel between two planets.
Each case starts with two positive integers N and M , indicating the number of planets and the number of channels.
(2<=N<=200000, 1<=M<=1000000)
Next M lines each contains two positive integers A and B, indicating a channel between planet A and B in the system. Planets are numbered by 1..N.
A line with two integers '0' terminates the input.
1 2
1 3
1 4
2 3
0 0
- #include<iostream>
- #include<cstdio>
- #include<algorithm>
- #include<cstring>
- #include<queue>
- using namespace std;
- queue<int>pq;
- struct edge {
- int fr;
- int to;
- int next;
- }e[], e2[];
- int cnt, scc_cnt, ccnt, tim;
- int head[], head2[], dfn[], low[], stk[], col[],d[], tp,dis,node;
- bool in_stk[], vis[];
- int ans = ;
- void dfs(int x, int fa) {
- d[x] = dis++;
- for (int i = head2[x]; i != -; i = e2[i].next) {
- int v = e2[i].to;
- if (v == fa)continue;
- if (!vis[v]) {
- vis[v] = ;
- dfs(v, x);
- }
- }
- return;
- }
- void bfs(int x) {
- while (!pq.empty())pq.pop();
- pq.push(x);
- memset(d, , sizeof(d));
- memset(vis, , sizeof(vis));
- while (!pq.empty()) {
- int s = pq.front(); pq.pop();
- for (int i = head2[s]; i != -; i = e2[i].next) {
- int v = e2[i].to;
- if (!vis[v]) {
- vis[v] = ;
- d[v] = d[s] + ;
- pq.push(v);
- if (d[v] > ans) {
- node = v;
- ans = d[v];
- }
- }
- }
- }
- }
- void Tarjan(int u, int fa, int id) {
- dfn[u] = low[u] = ++tim;
- in_stk[u] = ;
- stk[tp++] = u;
- for (int i = head[u]; i != -; i = e[i].next) {
- int v = e[i].to;
- if (!dfn[v]) {
- Tarjan(v, u, i);
- if (low[v] < low[u])low[u] = low[v];
- }
- else if (in_stk[v] && ((i ^ ) != id)) {
- if (dfn[v] < low[u])low[u] = dfn[v];//这里使用dfn[v]和low[v]都可以
- }
- }
- if (dfn[u] == low[u]) {
- scc_cnt++;
- do {
- tp--;
- int tt = stk[tp];
- col[tt] = scc_cnt;
- in_stk[tt] = ;
- } while (stk[tp] != u);
- }
- }
- void add(int x, int y) {
- e[cnt].fr = x;
- e[cnt].to = y;
- e[cnt].next = head[x];
- head[x] = cnt++;
- }
- void add2(int x, int y) {
- e2[ccnt].fr = x;
- e2[ccnt].to = y;
- e2[ccnt].next = head2[x];
- head2[x] = ccnt++;
- }
- int main() {
- int n, m;
- scanf("%d%d", &n, &m);
- while (n || m) {
- cnt = ;
- tp = ;
- scc_cnt = ;
- ccnt = ;
- ans = ;
- tim = ;
- memset(vis, , sizeof(vis));
- memset(in_stk, , sizeof(in_stk));
- memset(col, , sizeof(col));
- memset(head, -, sizeof(head));
- memset(head2, -, sizeof(head2));
- memset(dfn, , sizeof(dfn));
- memset(low, , sizeof(low));
- while (m--) {
- int a, b;
- scanf("%d%d", &a, &b);
- add(a, b);
- add(b, a);
- }
- for (int i = ; i <= n; i++) {
- if (!dfn[i]) {
- Tarjan(i, -, -);
- }
- }
- for (int i = ; i < cnt; i += ) {
- if (col[e[i].fr] != col[e[i].to]) {
- add2(col[e[i].fr], col[e[i].to]);
- add2(col[e[i].to], col[e[i].fr]);
- }
- }
- bfs();
- bfs(node);
- cout << ccnt / - ans << endl;
- scanf("%d%d", &n, &m);
- }
- return ;
- }
【HDOJ4612】【双连通分量缩点+找树的直径】的更多相关文章
- HDU 4612 Warm up(双连通分量缩点+求树的直径)
思路:强连通分量缩点,建立一颗新的树,然后求树的最长直径,然后加上一条边能够去掉的桥数,就是直径的长度. 树的直径长度的求法:两次bfs可以求,第一次随便找一个点u,然后进行bfs搜到的最后一个点v, ...
- HDU 3686 Traffic Real Time Query System(双连通分量缩点+LCA)(2010 Asia Hangzhou Regional Contest)
Problem Description City C is really a nightmare of all drivers for its traffic jams. To solve the t ...
- POJ3177 Redundant Paths(边双连通分量+缩点)
题目大概是给一个无向连通图,问最少加几条边,使图的任意两点都至少有两条边不重复路径. 如果一个图是边双连通图,即不存在割边,那么任何两个点都满足至少有两条边不重复路径,因为假设有重复边那这条边一定就是 ...
- 训练指南 UVA - 11324(双连通分量 + 缩点+ 基础DP)
layout: post title: 训练指南 UVA - 11324(双连通分量 + 缩点+ 基础DP) author: "luowentaoaa" catalog: true ...
- HDU 4612 Warm up (边双连通分量+缩点+树的直径)
<题目链接> 题目大意:给出一个连通图,问你在这个连通图上加一条边,使该连通图的桥的数量最小,输出最少的桥的数量. 解题分析: 首先,通过Tarjan缩点,将该图缩成一颗树,树上的每个节点 ...
- Gym - 100676H H. Capital City (边双连通分量缩点+树的直径)
https://vjudge.net/problem/Gym-100676H 题意: 给出一个n个城市,城市之间有距离为w的边,现在要选一个中心城市,使得该城市到其余城市的最大距离最短.如果有一些城市 ...
- hdu4612 Warm up[边双连通分量缩点+树的直径]
给你一个连通图,你可以任意加一条边,最小化桥的数目. 添加一条边,发现在边双内是不会减少桥的.只有在边双与边双之间加边才有效.于是,跑一遍边双并缩点,然后就变成一棵树,这样要加一条非树边,路径上的点( ...
- poj 3177 Redundant Paths(边双连通分量+缩点)
链接:http://poj.org/problem?id=3177 题意:有n个牧场,Bessie 要从一个牧场到另一个牧场,要求至少要有2条独立的路可以走.现已有m条路,求至少要新建多少条路,使得任 ...
- 图论-桥/割点/双连通分量/缩点/LCA
基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个 ...
随机推荐
- 【环境】新建Maven工程步骤及报错解决方法
新建Maven工程步骤: 1.打开eclipse,File-New-Other-Maven-Maven project 点击Finish,即可创建一个Maven工程.Maven是内置的,不需要额外下载 ...
- 内联函数inline的用法
一.什么是内联函数 在C语言中,如果一些函数被频繁调用,不断地有函数入栈,即函数栈,会造成栈空间或栈内存的大量消耗.为了解决这个问题,特别的引入了inline修饰符,表示为内联函数. 栈空间就是指放 ...
- C++ 解析一
C++ 类和对象C++ 在 C 语言的基础上增加了面向对象编程,C++ 支持面向对象程序设计.类是 C++ 的核心特性,通常被称为用户定义的类型.类用于指定对象的形式,它包含了数据表示法和用于处理数据 ...
- 深入理解 Java 虚拟机——走近 Java
1.1 - 概述 Java 总述:Java 不仅是一门编程语言,还是一个由一系列 计算机软件 和 规范 形成的技术体系,这个技术体系提供了完整的用于软件开发和跨平台部署的支持环境,并广泛应用于 嵌入式 ...
- unity中键盘WASD控制。(WS控制物体前后移动,AD控制左右旋转。)
private float rotateSpeed = 30f; private float movespeed = 5; void FixedUpdate() { //第一种控制移动 float h ...
- unity中手机触摸代码
#elif UNITY_IOS || UNITY_ANDROID if(Input.touchCount <= 0) { return;/ ...
- struts访问
struts基本工程结构: 1. struts.xml支持语法提示;2. struts.xml配置常量, 用来覆盖struts.properties中的默认常量配置 一般情况下, 这个配置放在str ...
- bzoj1261
题解: 看到了树 很明显就是树形dp吗 然后随便yy一下方程就好了 代码: #include<bits/stdc++.h> using namespace std; int n,j; ], ...
- Eclipse界面简介
下载安装完成后,Eclipse的界面如下: (6)为eclipse的perspective(视图方案)由于安装的是for Java development的eclipse,故视图界面默认 为使用Jav ...
- openpyxl读取Excel数据
#! Python3 #-*- coding:utf8 -*- import openpyxl #载入表格内容 wb=openpyxl.load_workbook('e:\\work\\newFile ...