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.

中文说明

为了从一个F(1<=F<=5000)放牧区(编号为1…F)到另一个放牧区,贝西和其他牛群被迫穿过腐烂的苹果树附近。奶牛现在已经厌倦了经常被强迫走一条特定的路,并且想要建造一些新的路,这样它们就可以在任何一对田地之间选择至少两条独立的路。它们目前在每对字段之间至少有一条路由,并且希望至少有两条。当然,他们只能在从一个领域到另一个领域的官方道路上旅行。

给出当前一组R(F-1<=R<=10000)路径的描述,每个路径正好连接两个不同的字段,确定必须构建的新路径(每个路径正好连接两个字段)的最小数目,以便在任何一对字段之间至少有两个单独的路径。如果路线不使用相同的路径,则认为它们是分开的,即使它们沿途访问相同的中间字段也是如此。

同一对字段之间可能已经有多条路径,您也可以构建一条新路径,将同一字段与其他路径连接起来。

输入

第1行:两个空格分隔的整数:f和r

行2…r+1:每行包含两个空格分隔的整数,这些整数是某些路径端点处的字段。

输出

第1行:一个整数,它是必须构建的新路径数。

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
2
3
4
5
5
6
7

Java实现冗余路径Redundant Paths的更多相关文章

  1. Luogu2860 [USACO06JAN]冗余路径Redundant Paths

    Luogu2860 [USACO06JAN]冗余路径Redundant Paths 给定一个连通无向图,求至少加多少条边才能使得原图变为边双连通分量 \(1\leq n\leq5000,\ n-1\l ...

  2. 洛谷 P2860 [USACO06JAN]冗余路径Redundant Paths 解题报告

    P2860 [USACO06JAN]冗余路径Redundant Paths 题目描述 为了从F(1≤F≤5000)个草场中的一个走到另一个,贝茜和她的同伴们有时不得不路过一些她们讨厌的可怕的树.奶牛们 ...

  3. 缩点【洛谷P2860】 [USACO06JAN]冗余路径Redundant Paths

    P2860 [USACO06JAN]冗余路径Redundant Paths 为了从F(1≤F≤5000)个草场中的一个走到另一个,贝茜和她的同伴们有时不得不路过一些她们讨厌的可怕的树.奶牛们已经厌倦了 ...

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

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

  5. luogu P2860 [USACO06JAN]冗余路径Redundant Paths

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

  6. 洛谷P2860 [USACO06JAN]冗余路径Redundant Paths

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

  7. [USACO06JAN] 冗余路径 Redundant Paths

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

  8. luogu P2860 [USACO06JAN]冗余路径Redundant Paths |Tarjan

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

  9. 【luogu P2860 [USACO06JAN]冗余路径Redundant Paths】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2860 考虑在无向图上缩点. 运用到边双.桥的知识. 缩点后统计度为1的点. 度为1是有一条路径,度为2是有两 ...

随机推荐

  1. 这份书单会告诉你,Java网络编程其实很重要

  2. 进程和线程—Python多线程编程

    进程和线程 进程 进程是一个执行中的程序.每个进程都拥有自己的地址空间.内存.数据栈以及其它用于跟踪执行的辅助数据. 一个程序运行就是一个进程(比如 QQ.微信或者其它软件): 进程可以通过派生新的进 ...

  3. python实现登录密码重置简易操作

    需求: 1.用户输入密码正确登录 2.用户输入密码错误退出并调用函数继续输入 3.用户输入密码符合原先给定的一个值时,允许用户重置密码,并且可以用新密码登录 4.输入三次后禁止输入 虽然贴别的简单,但 ...

  4. 计算python内部数据结构时间效率-源代码

    #Author:qinjiaxi '''本程序计算各种循环的时间效率''' from timeit import Timer def test1(n): li = [] for i in range( ...

  5. [Abp vNext 入坑分享] - 7.Automapper与validation的使用

    简要说明 [项目源码] [章节目录] 本文主要介绍Automapper与Validation的使用方法.首先使用Automapper的目的是引入组件完成entity与dto之间的转换以达到简化代码的目 ...

  6. 「雕爷学编程」Arduino动手做(7)——旋转电位器模块

    37款传感器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器,依照实践(动手试试)出真知的理念,以学习和交流为目的,这里准备逐一做做实验 ...

  7. 虚拟机安装配置(VMware与CentOS安装)

    VMware下载地址: https://www.vmware.com/cn/products/workstation-pro/workstation-pro-evaluation.html centO ...

  8. 流复制-pg_basebackup (没有自定义表空间)

    一.组成部分 1.walsender进程是用来发送WAL日志记录的 2.walreceiver进程是用来接收WAL日志记录的 3.startup进程是用来apply日志的 二.主库配置 1.授权账号, ...

  9. Postgres的索引01

    一.PG 9.3有以下索引类型 1.b-tree 1.1支持前导模糊查询,如xxx%或者^'xxx' 1.2忽略大小写字符前导模糊查询,如ILIKE 'XXX%'或者~*'^xxx' 1.3支持常见的 ...

  10. mysql小白系列_13 Online DDL

    Online DDL: 一.FIC之前的添加删除二级索引: 1.首先创建临时表,定义目标新表的选项和索引 2.逐行拷贝数据到临时表 3.插入行时更新索引信息 4.数据全部被拷贝到新表后,删除旧表,re ...