WUSTOJ 1318: 区间的连通性(Java)

题目链接:🔗1318: 区间的连通性
参考博客:🔗wust oj 1318 区间的连通性(贪心)——wust_zwl的博客

Description

题目包含多组数据,你有一个集合,该集合的元素为形如(x,y)的区间,两个区间1:(a,b)、2:(c,d),如果c < a < d或者c < b < d说明1号区间能到达2号区间,当然如果2号区间能到3号区间的话,那么1号区间也能到达3号区间。(该性质具有传递性)
现在给你n个操作,操作分为两种:
1.“1 x y”(x < y),将区间加入集合中。(区间按照加入的顺序编号)
2.“2 a b”(a != b),问你第a个区间能否到达第b个区间。

Input

首先是一个n(1<=n<=200),表示操作数,然后有n行,每行有三个数,代表一个操作。
输入保证数据都在10^9的范围内。

Output

第2种操作时,如果a能到达b,输出“YES”,否则输出“NO”(不带引号)。

Sample Input

5
1 1 5
1 5 11
2 1 2
1 2 9
2 1 2

Sample Output

NO
YES

分析💬

  • 显然区间端点需要保存,用int型的二维数组collection[201][2]即可。
  • 不同区间之间是否连通,直接用boolean型的二维数组connected[opNum + 1][opNum + 1]表示。
  • 操作1,将区间端点保存到collection中,并设置connected对应的能直接连通的值为true
  • 操作2,判断区间a和区间b是否连通,如果连通,直接输出YES,如果不连通,设置connected对应的能间接连通的值为true,然后再次判断是否连通,输出YES或者NO

易错点:不要想着统一输入完后,再输出。就拿Simple Input来说,会输出两个YES

代码

/**
 * Time 711ms
 * @author wowpH
 * @version 2.4
 * @date 2019年6月21日下午5:09:32
 * Environment: Windows 10
 * IDE Version: Eclipse 2019-3
 * JDK Version: JDK1.8.0_112
 */

import java.io.InputStreamReader;
import java.util.Scanner;

public class Main {
	private int intervalNum;// 操作1的次数,也就是区间的个数
	// 集合,存储区间的端点,下标从1开始
	private int[][] collection = new int[201][2];
	private boolean[][] connected;// 存储区间是否连通
	private int a, b;// 操作的后两个数

	public Main() {
		Scanner sc = new Scanner(new InputStreamReader(System.in));
		int opNum, flag;// 总操作次数,操作类型(1或2)

		while (sc.hasNext()) {
			intervalNum = 0;// 初始化区间的个数
			opNum = sc.nextInt();// 总的操作次数
			connected = new boolean[opNum + 1][opNum + 1];// 存储区间是否连通
			for (int i = 0; i < opNum; ++i) {
				flag = sc.nextInt();// 操作类型
				a = sc.nextInt();
				b = sc.nextInt();
				if (1 == flag) {
					opOne();// 操作1
				} else {
					opTwo();// 操作2
				}
			}
		}
		sc.close();
	}

	// 操作1
	private void opOne() {
		++intervalNum;
		collection[intervalNum][0] = a;// 保存区间端点
		collection[intervalNum][1] = b;
		directlyConnected();// 直接连通
	}

	// 操作2
	private void opTwo() {
		if (true == connected[a][b]) {
			System.out.println("YES");// 区间b与区间c连通
		} else {
			indirectlyConnected();// 间接连通
			if (true == connected[a][b]) {
				System.out.println("YES");
			} else {
				System.out.println("NO");
			}
		}
	}

	// 直接连通
	private void directlyConnected() {
		for (int j = 1; j < intervalNum; ++j) {// 遍历前面的intervalNum-1个区间
			// 区间intervalNum可以到区间j
			if (collection[j][0] < a && a < collection[j][1]
					|| collection[j][0] < b && b < collection[j][1]) {
				connected[intervalNum][j] = true;
			}
			// 区间j可以到区间intervalNum
			if (a < collection[j][0] && collection[j][0] < b
					|| a < collection[j][1] && collection[j][1] < b) {
				connected[j][intervalNum] = true;
			}
		}
	}

	// 间接连通
	private void indirectlyConnected() {
		// 遍历所有区间,作为中间区间
		for (int center = 1; center <= intervalNum; ++center) {
			// 遍历所有区间,作为左边区间
			for (int left = 1; left <= intervalNum; ++left) {
				if (false == connected[left][center]) {
					continue;// 区间left和区间center不连通,继续下一个区间
				}
				// 区间left和区间center连通,遍历所有区间,作为右边区间
				for (int right = 1; right <= intervalNum; ++right) {
					// 区间center和right连通
					if (true == connected[center][right]) {
						connected[left][right] = true;// 传递性
					}
				}
			}
		}
	}

	public static void main(String[] args) {
		new Main();
	}
}
posted @ 2019-06-22 16:15  wowpH  阅读(231)  评论(0编辑  收藏  举报