算法笔记_142:无向图的欧拉回路求解(Java)
目录
1 问题描述
Time Limit: 1000MS | Memory Limit: 65536K | |||
Total Submissions: 8998 | Accepted: 3018 | Special Judge |
Description
The streets in Johnny's town were named by integer numbers from 1 to n, n < 1995. The junctions were independently named by integer numbers from 1 to m, m <= 44. No junction connects more than 44 streets. All junctions in the town had different numbers. Each street was connecting exactly two junctions. No two streets in the town had the same number. He immediately started to plan his round trip. If there was more than one such round trip, he would have chosen the one which, when written down as a sequence of street numbers is lexicographically the smallest. But Johnny was not able to find even one such round trip.
Help Johnny and write a program which finds the desired shortest round trip. If the round trip does not exist the program should write a message. Assume that Johnny lives at the junction ending the street appears first in the input with smaller number. All streets in the town are two way. There exists a way from each street to another street in the town. The streets in the town are very narrow and there is no possibility to turn back the car once he is in the street
Input
Output
Sample Input
- 1 2 1
- 2 3 2
- 3 1 6
- 1 2 5
- 2 3 3
- 3 1 4
- 0 0
- 1 2 1
- 2 3 2
- 1 3 3
- 2 4 4
- 0 0
- 0 0
Sample Output
- 1 2 3 5 4 6
- Round trip does not exist.
Source
2 解决方案
具体代码如下:
- package com.liuzhen.practice;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.Comparator;
- import java.util.Scanner;
- public class Main {
- public static int MAX = 100; //题意说明,最多44个路口
- public static int start; // Johnny出发起点
- public static int[] id = new int[MAX];
- public static int[] degree = new int[MAX]; //用于计算给定图每个顶点的度
- public static boolean[] used = new boolean[2000]; //用于判断图中相应边是否被遍历
- public static int[] path = new int[MAX];
- public static int count; //用于统计行走路径的街道数
- public static ArrayList<String> result = new ArrayList<String>();
- class MyComparator implements Comparator<edge> {
- public int compare(edge o1, edge o2) {
- if(o1.street > o2.street)
- return 1;
- else if(o1.street < o2.street)
- return -1;
- else
- return 0;
- }
- }
- static class edge {
- public int a; //边的起点
- public int b; //边的终点
- public int street; //街道
- public edge(int a, int b, int street) {
- this.a = a;
- this.b = b;
- this.street = street;
- }
- }
- //寻找顶点a的根节点
- public int find(int[] id, int a) {
- int root = a;
- while(id[root] >= 0) {
- root = id[root];
- }
- int i;
- int k = a;
- while(k != root) {
- i = id[k];
- id[k] = root;
- k = i;
- }
- return root;
- }
- //合并顶点a和顶点b所在的树
- public void union(int[] id, int a, int b) {
- int rootA = find(id, a);
- int rootB = find(id, b);
- int rootNum = id[rootA] + id[rootB];
- if(id[rootA] < id[rootB]) {
- id[rootB] = rootA;
- id[rootA] = rootNum;
- } else{
- id[rootA] = rootB;
- id[rootB] = rootNum;
- }
- return;
- }
- public void init() {
- for(int i = 0;i < 50;i++) {
- id[i] = -1; //初始化所有顶点所在树的根节点编号为-1
- degree[i] = 0;
- path[i] = -1;
- count = 0;
- }
- for(int i = 0;i < 2000;i++) {
- used[i] = false;
- }
- return;
- }
- public boolean judge(ArrayList<edge>[] map) {
- int root = find(id, start);
- for(int i = 0;i < MAX;i++) {
- if(map[i].size() == 0)
- continue;
- Collections.sort(map[i], new MyComparator());
- for(int j = 0;j < map[i].size();j++) {
- if(find(id, map[i].get(j).b) != root)
- return false;
- }
- }
- for(int i = 0;i < MAX;i++) {
- if(degree[i] % 2 != 0)
- return false;
- }
- return true;
- }
- public void dfs(ArrayList<edge>[] map, int start) {
- for(int i = 0;i < map[start].size();i++) {
- if(!used[map[start].get(i).street]) {
- used[map[start].get(i).street] = true;
- path[count++] = map[start].get(i).street;
- dfs(map, map[start].get(i).b);
- }
- }
- }
- public static void main(String[] args) {
- Main test = new Main();
- Scanner in = new Scanner(System.in);
- while(true) {
- int a1 = in.nextInt();
- int b1 = in.nextInt();
- if(a1 == 0 && b1 == 0)
- break;
- int c1 = in.nextInt();
- start = Math.min(a1, b1); //Johnny出发起点
- test.init(); //初始化输入顶点的度和所在树的根节点
- @SuppressWarnings("unchecked")
- ArrayList<edge>[] map = new ArrayList[MAX];
- for(int i = 0;i < MAX;i++) {
- map[i] = new ArrayList<edge>();
- }
- map[a1].add(new edge(a1, b1, c1));
- map[b1].add(new edge(b1, a1, c1));
- degree[a1]++;
- degree[b1]++;
- test.union(id, a1, b1); //合并顶点a1和顶点b1所在树
- while(true) {
- int a = in.nextInt();
- int b = in.nextInt();
- if(a == 0 && b == 0)
- break;
- int c = in.nextInt();
- map[a].add(new edge(a, b, c));
- map[b].add(new edge(b, a, c));
- degree[a]++;
- degree[b]++;
- test.union(id, a, b);
- }
- String tempR = "";
- if(test.judge(map)) {
- test.dfs(map, start);
- for(int i = 0;i < count;i++) {
- tempR = tempR + path[i] + " ";
- }
- } else {
- tempR = "Round trip does not exist.";
- }
- result.add(tempR);
- }
- for(int i = 0;i < result.size();i++)
- System.out.println(result.get(i));
- }
- }
运行结果:
- 1 2 1
- 2 3 2
- 3 1 6
- 1 2 5
- 2 3 3
- 3 1 4
- 0 0
- 1 2 1
- 2 3 2
- 1 3 3
- 2 4 4
- 0 0
- 0 0
- 1 2 3 5 4 6
- Round trip does not exist.
参考资料:
1.欧拉回路
算法笔记_142:无向图的欧拉回路求解(Java)的更多相关文章
- 算法笔记_141:无向图的欧拉回路判断问题(Java)
目录 1 问题描述 2 解决方案 1 问题描述 Problem Description 欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路.现给定一个图,问是否存在欧拉回 ...
- 算法笔记_148:有向图欧拉回路求解(Java)
目录 1 问题描述 2 解决方案 1 问题描述 Description A catenym is a pair of words separated by a period such that t ...
- 算法笔记_183:历届试题 九宫重排(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成 ...
- 算法笔记_177:历届试题 城市建设(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 栋栋居住在一个繁华的C市中,然而,这个城市的道路大都年久失修.市长准备重新修一些路以方便市民,于是找到了栋栋,希望栋栋能帮助他. C市中有 ...
- 算法笔记_135:格子取数问题(Java)
目录 1 问题描述 2 解决方案 1 问题描述 有n*n个格子,每个格子里有正数或者0,从最左上角往最右下角走,只能向下和向右走,一共走两次(即从左上角往右下角走两趟),把所有经过的格子里的数加起 ...
- 算法笔记_046:跳台阶问题(Java)
目录 1 问题描述 2 解决方案 2.1 递归法 2.2 迭代法 1 问题描述 一个台阶总共有n级,如果一次可以跳1级,也可以跳2级,求总共有多少种跳法. 2 解决方案 2.1 递归法 如果整个台 ...
- 算法笔记_045:币值最大化问题(Java)
目录 1 问题描述 2 解决方案 2.1 动态规划法 1 问题描述 给定一排n个硬币,其面值均为正整数c1,c2,...,cn,这些整数并不一定两两不同.请问如何选择硬币,使得在其原始位置互不相邻 ...
- 算法笔记_029:约瑟夫斯问题(Java)
目录 1 问题描述 2 解决方案 1 问题描述 引用自<算法设计与分析基础>第三版: 约瑟夫斯问题,是以弗拉瓦斯.约瑟夫斯(Flavius Josephus)的名字命名的.约瑟夫斯是一 ...
- 算法笔记_051:荷兰国旗问题(Java)
目录 1 问题描述 2 解决方案 1 问题描述 现有n个红白蓝三种不同颜色的小球,乱序排列在一起,请通过两两交换任意两个球,使得从左至右的球依次为红球.白球.蓝球.这个问题之所以叫荷兰国旗,是因为 ...
随机推荐
- WEB架构师成长之路 一
一 .你必须学习面向对象的基础知识 1.降低软件开发的复杂度 2.提高软件开发的效率 3.提高软件质量:可维护性,可扩展性,可重用性等. 提高软件质量:可维护性,可扩展性,可重用性等,再具体点,就是高 ...
- [CodeForces850C]Arpa and a game with Mojtaba
题目大意: 给你一个包含n个数的数列,两个人轮流对数列进行如下操作: 选择一个质数p和一个正整数k,将数列中所有能被p^k整除的数除以p^k. 最后不能操作者负. 问先手是否有必胜策略. 思路: 显然 ...
- Problem G: 切煎饼
Description 王小二自夸刀工不错,有人放一张大的圆煎饼在砧板上,问他:饼不允许离开砧板,切100刀最多能切多少块? Input 多组测试数据,每组输入1个整数,代表切的刀数 Output 每 ...
- hdu 3046 最小割
每个栅栏其实就是一条边,修一些栅栏,使得狼不能抓到羊,其实就是求一个割,使得羊全在S中,狼全在T中. #include <cstdio> #include <cstring> ...
- c# -- Form1_Load()不被执行的三个解决方法
我的第一个c#练习程序,果然又出现问题了...在Form1_Load() not work.估计我的人品又出现问题了. 下面实现的功能很简单,就是声明一个label1然后,把它初始化赋值为hello, ...
- C# -- 学习笔记之基础篇
由于要做一个系统,需要用到搜索引擎开发的很多知识点.对于开发语言的选择,我一般不是擅长什么才选择什么的,而是通过对比之后,考虑开发时间和难易程度来选择.尽管现在的开发经验还不足,也只能凭借自己弱弱的判 ...
- python学习一月总结_汇总大牛们的思想_值得收藏
''' 下面是我汇总的我学习一个月python(version:3.3.2)的所有笔记 你可以访问:http://www.python.org获取更多信息 你也可以访问:http://www.cnbl ...
- ZigBee和Z-Wave的区别与未来
http://tech.c114.net/164/a702667.html ZigBee和Z-Wave短距离无线技术都用于远程监控和控制,但两种技术的规格和应用却不同.在美国应用越来越广泛的家庭局域网 ...
- Mac OS上的远程桌面
最近在做Mac上面的开发,经常在win7和Mac两台电脑上操作,两个键盘,两个鼠标,搞得头都大了,所以干脆把Mac机器远程到win7上面,统一来做,方便些..哈哈!说实话,Mac键盘那些按键真还有点特 ...
- NHibernate Configuring
NHibernate引用程序中有几个关键组件,如下图所示: 初始化时,NHibernate应用程序将生成一个配置对象.本节中,我们通过设置App.config文件来生成该配置对象.该对象负责加载映射信 ...