目录

1 问题描述

2 解决方案

 


1 问题描述

Description

In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numbered 1..F) to another field, Bessie and the rest of the herd are forced to cross near the Tree of Rotten Apples. The cows are now tired of often being forced to take a particular path and want to build some new paths so that they will always have a choice of at least two separate routes between any pair of fields. They currently have at least one route between each pair of fields and want to have at least two. Of course, they can only travel on Official Paths when they move from one field to another.

Given a description of the current set of R (F-1 <= R <= 10,000) paths that each connect exactly two different fields, determine the minimum number of new paths (each of which connects exactly two fields) that must be built so that there are at least two separate routes between any pair of fields. Routes are considered separate if they use none of the same paths, even if they visit the same intermediate field along the way.

There might already be more than one paths between the same pair of fields, and you may also build a new path that connects the same fields as some other path.

Input

Line 1: Two space-separated integers: F and R

Lines 2..R+1: Each line contains two space-separated integers which are the fields at the endpoints of some path.

Output

Line 1: A single integer that is the number of new paths that must be built.

Sample Input

7 7
1 2
2 3
3 4
2 5
4 5
5 6
5 7

Sample Output

2

Hint

Explanation of the sample:

One visualization of the paths is:

   1   2   3
+---+---+
| |
| |
6 +---+---+ 4
/ 5
/
/
7 +

Building new paths from 1 to 6 and from 4 to 7 satisfies the conditions.

   1   2   3
+---+---+
: | |
: | |
6 +---+---+ 4
/ 5 :
/ :
/ :
7 + - - - -

Check some of the routes: 
1 – 2: 1 –> 2 and 1 –> 6 –> 5 –> 2 
1 – 4: 1 –> 2 –> 3 –> 4 and 1 –> 6 –> 5 –> 4 
3 – 7: 3 –> 4 –> 7 and 3 –> 2 –> 5 –> 7 
Every pair of fields is, in fact, connected by two routes.

It's possible that adding some other path will also solve the problem (like one from 6 to 7). Adding two paths, however, is the minimum.

Source

 

2 解决方案

具体代码如下:

package com.liuzhen.practice;

import java.util.ArrayList;
import java.util.Scanner;
import java.util.Stack; public class Main {
public static int n; //给定图的顶点数
public static int count; //记录遍历次序
public static int[] DFN;
public static int[] Low;
public static int[] parent; //parent[i] = j,表示顶点i的直接父母顶点为j
public static Stack<Integer> stack;
public static ArrayList<edge>[] map;
public static ArrayList<edge> ans; //存储给定图中为桥的边 static class edge {
public int a; //边的起点
public int b; //边的终点
public boolean used; //表示边是否已被访问 public edge(int a, int b) {
this.a = a;
this.b = b;
this.used = false;
}
} @SuppressWarnings("unchecked")
public void init() {
count = 0;
DFN = new int[n + 1];
Low = new int[n + 1];
parent = new int[n + 1];
stack = new Stack<Integer>();
map = new ArrayList[n + 1];
ans = new ArrayList<edge>();
for(int i = 1;i <= n;i++) {
DFN[i] = -1;
Low[i] = -1;
parent[i] = -1;
map[i] = new ArrayList<edge>();
}
} public void TarJan(int start, int father) {
DFN[start] = count++;
Low[start] = DFN[start];
parent[start] = father;
stack.push(start);
for(int i = 0;i < map[start].size();i++) {
edge temp = map[start].get(i);
if(temp.used)
continue;
int t = temp.b;
for(int p = 0;p < map[t].size();p++) {
if(map[t].get(p).b == temp.a) {
map[t].get(p).used = true;
break;
}
}
temp.used = true;
int j = temp.b;
if(DFN[j] == -1) {
TarJan(j, start);
Low[start] = Math.min(Low[start], Low[j]);
if(Low[j] > DFN[start]) //当边temp为割边(或者桥)时
ans.add(temp);
} else if(j != parent[start]) { //当j不是start的直接父母节点时
Low[start] = Math.min(Low[start], DFN[j]);
}
}
} public void getResult() {
for(int i = 1;i <= n;i++) {
if(parent[i] == -1)
TarJan(i, 0);
}
int[] degree = new int[n + 1];
for(int i = 0;i < ans.size();i++) {
int a = ans.get(i).a;
int b = ans.get(i).b;
degree[a]++;
degree[b]++;
}
int result = 0;
for(int i = 1;i <= n;i++) {
if(degree[i] == 1)
result++;
}
result = (result + 1) / 2;
System.out.println(result);
return;
} public static void main(String[] args) {
Main test = new Main();
Scanner in = new Scanner(System.in);
n = in.nextInt();
int m = in.nextInt();
test.init();
for(int i = 0;i < m;i++) {
int a = in.nextInt();
int b = in.nextInt();
map[a].add(new edge(a, b));
map[b].add(new edge(b, a));
}
test.getResult();
}
}

运行结果:

7 7
1 2
2 3
3 4
2 5
4 5
5 6
5 7
2

参考资料:

1.pku 3177 (3352) Redundant Paths

2. PKU3352(Road Construction)-图的双连通,桥

算法笔记_150:图论之双连通及桥的应用(Java)的更多相关文章

  1. 算法笔记_149:图论之桥的应用(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 1310 One-way traffic In a certain town there are n intersections connected ...

  2. 学习Java 以及对几大基本排序算法(对算法笔记书的研究)的一些学习总结(Java对算法的实现持续更新中)

    Java排序一,冒泡排序! 刚刚开始学习Java,但是比较有兴趣研究算法.最近看了一本算法笔记,刚开始只是打算随便看看,但是发现这本书非常不错,尤其是对排序算法,以及哈希函数的一些解释,让我非常的感兴 ...

  3. 算法笔记_041:寻找和为定值的多个数(Java)

    目录 1 问题描述 2 解决方案 1 问题描述 输入两个整数n和sum,要求从数列1,2,3,...,n中随意取出几个数,使得它们的和等于sum,请将其中所有可能的组合列出来. 2 解决方案 上述问题 ...

  4. 图论--边双连通V-DCC缩点

    // tarjan算法求无向图的割点.点双连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> ...

  5. 算法笔记_119:蓝桥杯第六届省赛(Java语言A组)试题解答

     目录 1 熊怪吃核桃 2 星系炸弹 3 九数分三组 4 循环节长度 5 打印菱形 6 加法变乘法 7 牌型种数 8 移动距离 9 垒骰子 10 灾后重建   前言:以下试题解答代码部分仅供参考,若有 ...

  6. 算法笔记_056:蓝桥杯练习 未名湖边的烦恼(Java)

    目录 1 问题描述 2 解决方案 2.1 递归法 2.2 递推法   1 问题描述 问题描述 每年冬天,北大未名湖上都是滑冰的好地方.北大体育组准备了许多冰鞋,可是人太多了,每天下午收工后,常常一双冰 ...

  7. 算法笔记_204:第四届蓝桥杯软件类决赛真题(Java语言C组)

    目录 1 好好学习 2 埃及分数 3 金蝉素数 4 横向打印二叉树 5 危险系数 6 公式求值   前言:以下代码仅供参考,若有错误欢迎指正哦~ 1 好好学习 汤姆跟爷爷来中国旅游.一天,他帮助中国的 ...

  8. 算法笔记_201:第三届蓝桥杯软件类决赛真题(Java本科)

    目录 1 数量周期 2 提取子串 3 源码变换 4 古代赌局 5 火柴游戏   前言:以下代码仅供参考,若有错误欢迎指正哦~ 1 数量周期 [结果填空](满分9分) 复杂现象背后的推动力,可能是极其简 ...

  9. 算法笔记_206:第五届蓝桥杯软件类决赛真题(Java语言A组)

    目录 1 海盗分金币 2 六角幻方 3 格子放鸡蛋 4 排列序数 5 幂一矩阵 6 供水设施    前言:以下代码仅供参考,若有错误欢迎指正哦~ 1 海盗分金币 有5个海盗,相约进行一次帆船比赛. 比 ...

随机推荐

  1. [SDOI2017]数字表格 --- 套路反演

    [SDOI2017]数字表格 由于使用markdown的关系 我无法很好的掌控格式,见谅 对于这么简单的一道题竟然能在洛谷混到黑,我感到无语 \[\begin{align*} \prod\limits ...

  2. nginx fastcgi_buffers to an upstream response is buffered to a temporary file

    fastcgi_buffers 16 16k; 指定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答,如上所示,如果一个php脚本所产生的页面大小为256k,则会为其分配16个16k的缓冲区来缓 ...

  3. 20162304 实验一《Java开发环境的熟悉》实验报告

    Linux基础与Java开发环境 实验内容 1.熟悉Linux基础操作: 2.使用JDK编译.运行简单的Java程序: 实验要求 1.学习<Linux基础入门(新版)> 2.完成实验.撰写 ...

  4. python开发_os.path

    在python中,os.path模块在处理路径的时候非常有用 下面是我做的demo 运行效果: ========================================= 代码部分: ==== ...

  5. HDU 5671 Matrix 水题

    Matrix 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5671 Description There is a matrix M that has ...

  6. 原生JavaScript---正则表达式

    JavaScript 中正则的性能比想象中的低很多.能用字符串方法搞定的,尽量别用正则.------玉伯 抛开性能不谈,一起来看看正则表达式怎么用吧! 先看看JavaScript正则表达式中一些特殊字 ...

  7. jdbc preparestatement和preparestatement区别

    1.preparestatement预编译,预编译指的是DB的编译器,会对此sql语句提前编译.然后将预编译的结果缓存到数据库中,下次执行时替换参数直接执行编译过的语句. 记住:数据库也是有编译器的, ...

  8. centos7 yum安装配置redis 并设置密码

    原文:https://www.cnblogs.com/fanlinglong/p/6635828.html centos7 yum安装配置redis 并设置密码 1.设置Redis的仓库地址 yum ...

  9. cocos2d-x HelloWorld 代码一撇

        本节简单对新生成的hellowrold 项目相关代码进行简单分析,具体以代码注释的方式展示给大家.代码相对简单些,在此不作过多赘述,直接上码: int APIENTRY _tWinMain(H ...

  10. LINUX下给软件创建桌面图标

    转自:http://www.cnblogs.com/Rapheal/p/3610411.html?utm_source=tuicool&utm_medium=referral 最近在折腾lin ...