题目3 : 树上的三角形
时间限制:4000ms
单点时限:2000ms
内存限制:256MB
-
2 5 1 2 5 1 3 20 2 4 30 4 5 15 2 3 4 3 5 5 1 4 32 2 3 100 3 5 45 4 5 60 2 1 4 1 3
样例输出 -
Case #1: No Yes Case #2: No Yes
描述
有一棵树,树上有只毛毛虫。它在这棵树上生活了很久,对它的构造了如指掌。所以它在树上从来都是走最短路,不会绕路。它还还特别喜欢三角形,所以当它在树上爬来爬去的时候总会在想,如果把刚才爬过的那几根树枝/树干锯下来,能不能从中选三根出来拼成一个三角形呢?
输入
输入数据的第一行包含一个整数 T,表示数据组数。
接下来有 T 组数据,每组数据中:
第一行包含一个整数 N,表示树上节点的个数(从 1 到 N 标号)。
接下来的 N-1 行包含三个整数 a, b, len,表示有一根长度为 len 的树枝/树干在节点 a 和节点 b 之间。
接下来一行包含一个整数 M,表示询问数。
接下来M行每行两个整数 S, T,表示毛毛虫从 S 爬行到了 T,询问这段路程中的树枝/树干是否能拼成三角形。
1 ≤ T ≤ 5
小数据:1 ≤ N ≤ 100, 1 ≤ M ≤ 100, 1 ≤ len ≤ 10000
大数据:1 ≤ N ≤ 100000, 1 ≤ M ≤ 100000, 1 ≤ len ≤ 1000000000
输出
对于每组数据,先输出一行"Case #X:",其中X为数据组数编号,从 1 开始。
接下来对于每个询问输出一行,包含"Yes"或“No”,表示是否可以拼成三角形。
package TriangleOnTree;
import java.io.BufferedInputStream;
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
int[][] node;
String[] startEnd;
ArrayList<Integer> values;
int visit[];
ArrayList<Integer> stack;
boolean b;
public Main(int[][] node, String[] startEnd) {
this.node = node;
this.startEnd = startEnd;
}
public void calc() {
for (int i = 0; i < startEnd.length; i++) {
// 初始化
visit = new int[node[0].length];
values = new ArrayList<Integer>(node[0].length - 1);
stack = new ArrayList<Integer>();
int start = Integer.parseInt(startEnd[i].split(" ")[0]) - 1;
int end = Integer.parseInt(startEnd[i].split(" ")[1]) - 1;
this.path(start, end);
// System.out.println(i + ":");
// for (Integer v : values) {
// System.out.println(v);
// }
this.isTriangle();
}
}
public void isTriangle() {
boolean flag = false;
int n = values.size();
if (n >= 3) {
A: for (int i = 0; i < n - 2; i++) {
for (int j = i + 1; j < n - 1; j++) {
for (int k = j + 1; k < n; k++) {
int a = pd(values.get(i), values.get(j), values.get(k));
int b = pd(values.get(i), values.get(k), values.get(j));
int c = pd(values.get(j), values.get(k), values.get(i));
int tmp = a + b + c;
if (tmp == 3) {
flag = true;
break A;
}
}
}
}
}
if (flag)
System.out.println("Yes");
else
System.out.println("No");
}
int pd(int a, int b, int c) {
int k = a + b;
if (k > c)
return 1;
else
return 0;
}
public void path(int start, int end) {
for (int j = 0; j < node[start].length; j++) {
b = false;
// System.out.println("node["+start+"]["+j+"]:"+node[start][j]);
if (node[start][j] != 0 && visit[j] == 0 && visit[start] == 0) {
visit[start] = 1;
if (j != end) {
values.add(node[start][j]);
stack.add(start);
path(j, end);
if(b)
return ;
} else {
b = true;
values.add(node[start][j]);
break;
}
} else {
if (j == node[start].length - 1) {
visit[start] = 1;
visit[stack.get(stack.size() - 1)] = 0;
stack.remove(stack.size() - 1);
values.remove(values.size() - 1);
}
}
}
}
public static void main(String[] args) {
Scanner cin = new Scanner(new BufferedInputStream(System.in));
// 数据组数
int num = cin.nextInt();
cin.nextLine();
for (int i = 0; i < num; i++) {
// 节点个数
int NodeNum = cin.nextInt();
int[][] node = new int[NodeNum][NodeNum];
cin.nextLine();
for (int j = 1; j < NodeNum; j++) {
int start = cin.nextInt();
int end = cin.nextInt();
int value = cin.nextInt();
// System.out.println("node["+ (start-1) +"]["+ (end-1)
// +"]:"+value);
cin.nextLine();
// System.out.println(start);
// System.out.println(end);
node[start - 1][end - 1] = value;
node[end - 1][start - 1] = value;
}
int TestNum = cin.nextInt();
cin.nextLine();
String[] startEnd = new String[TestNum];
for (int j = 0; j < TestNum; j++) {
startEnd[j] = cin.nextLine();
}
System.out.println("Case #" + (i + 1) + ":");
Main tot = new Main(node, startEnd);
tot.calc();
}
cin.close();
}
}
本题提交未通过,欢迎纠错!当然,我用的方法是最原始、最容易想的方法。。。