开发者社区> johnwong> 正文

2013编程之美全国挑战赛第一场-树上的三角形

简介:
+关注继续查看

树上三角形

时间限制: 2000ms 内存限制: 256MB

描述

有一棵树,树上有只毛毛虫。它在这棵树上生活了很久,对它的构造了如指掌。所以它在树上从来都是走最短路,不会绕路。它还还特别喜欢三角形,所以当它在树上爬来爬去的时候总会在想,如果把刚才爬过的那几根树枝/树干锯下来,能不能从中选三根出来拼成一个三角形呢?

输入

输入数据的第一行包含一个整数 T,表示数据组数。
接下来有 T 组数据,每组数据中:
第一行包含一个整数 N,表示树上节点的个数(从 1 到 N 标号)。
接下来的 N-1 行包含三个整数 a, b, len,表示有一根长度为 len 的树枝/树干在节点 a 和节点 b 之间。
接下来一行包含一个整数 M,表示询问数。
接下来M行每行两个整数 S, T,表示毛毛虫从 S 爬行到了 T,询问这段路程中的树枝/树干是否能拼成三角形。

输出

对于每组数据,先输出一行"Case #X:",其中X为数据组数编号,从 1 开始。
接下来对于每个询问输出一行,包含"Yes"或“No”,表示是否可以拼成三角形。

数据范围

1 ≤ T ≤ 5
小数据:1 ≤ N ≤ 100, 1 ≤ M ≤ 100, 1 ≤ len ≤ 10000
大数据:1 ≤ N ≤ 100000, 1 ≤ M ≤ 100000, 1 ≤ len ≤ 1000000000


样例输入


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

思路很简单,Dijkstra算法求出最短路径,暂没考虑多条路径的情况。然后三角形判断。可是最后Wrong Answer。



import java.util.ArrayList;  
import java.util.Arrays;  
import java.util.HashMap;  
import java.util.Scanner;  

public class Main {  
    public static void main(String[] args) {  
        Scanner in = new Scanner(System.in);  
        int T = in.nextInt();  
        for (int i = 0; i < T; i++) {  
            int N = in.nextInt();  
            int[][] data = new int[N + 1][N + 1];  
            for (int j = 0; j < N - 1; j++) {  
                int from = in.nextInt();  
                int to = in.nextInt();  
                int cost = in.nextInt();  
                data[from][to] = cost;  
                data[to][from] = cost;  
            }  
            int Q = in.nextInt();  
            System.out.println("Case #" + (i+1) + ":");  
            for (int j = 0; j < Q; j++) {  
                int from = in.nextInt();  
                int to = in.nextInt();  
                int[] cost = new int[N + 1];  
                boolean[] isFind = new boolean[N + 1];  
                HashMap<Integer, ArrayList<Integer>> path = new HashMap<Integer, ArrayList<Integer>>();  
                int current = from;  
                isFind[current] = true;  
                // Dijstra from->to  
                for (int l = 1; l < N+1; l++) {  
                    int min = -1;  
                    for (int k = 1; k < N+1; k++) {  
                        if (data[current][k] > 0 && !isFind[k]) {  
                            int temp = cost[current] + data[current][k];  
                            if (cost[k] == 0 || temp < cost[k]) {  
                                ArrayList<Integer> newPath = new ArrayList<Integer>();  
                                newPath.add(data[current][k]);  
                                if (path.get(current) != null) {  
                                    newPath.addAll(path.get(current));  
                                    path.put(k, newPath);  
                                }  
                                path.put(k, newPath);  
                                cost[k] = temp;  
                            }  
                            if (min < 0 || cost[k] < cost[min]) {  
                                min = k;  
                            }  
                        }  
                    }  
                    current = min;  
//                  System.out.println("current:" + current);  
                    if (current < 0) {  
                        break;  
                    } else if (current == to) {  
                        break;  
                    }  
                    isFind[current] = true;  
                }  
                System.out.println(path.get(to));  
                // 寻找  
                if (path.get(to) != null) {  
                    Integer[] pathArray = path.get(to).toArray(new Integer[0]);  
                    boolean find = false;  
                    for (int ii=0; ii<pathArray.length; ii++) {  
                        for(int ij=ii+1;ij<pathArray.length; ij++){  
                            for(int ik=ij+1;ik<pathArray.length;ik++){  
//                              System.out.println("path:" + pathArray[ii] + " " + pathArray[ij] + " " + pathArray[ik]);  
                                if(pathArray[ii] + pathArray[ij] > pathArray[ik]  
                                        && pathArray[ij] + pathArray[ik] > pathArray[ii]  
                                        && pathArray[ik] + pathArray[ii] > pathArray[ij]){  
                                    find = true;  
                                    break;  
                                }  
                            }  
                            if(find)break;  
                        }  
                        if(find)break;  
                    }  
                    if(find)  
                        System.out.println("Yes");  
                    else   
                        System.out.println("No");  
                } else {  
                    System.out.println("No");  
                }  
            }  
        }  
    }  
}






版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Effective前端(3)用CSS画一个三角形
来源:https://zhuanlan.zhihu.com/p/26160325 三角形的场景很常见,打开一个页面可以看到各种各样的三角形: 由于div一般是四边形,要画个三角形并不是那么直观。你可以贴一张png,但是这种办法有点low,或者是用svg的形式,但是太麻烦。
937 0
Directx11教程(6) 画一个简单的三角形(2)
在上篇教程中,我们实现了在D3D11中画一个简单的三角形,但是,当我们改变窗口大小时候,三角形形状却随着窗口高宽比例改变而改变,如下图所示:           这是因为我们改变了窗口大小,但后缓冲大小在程序初始化时候,已经被指定,不随着窗口改变而改变,这样在视口映射下,我们所渲染的三角形就改变了形状。
930 0
C# Graphic 绘制圆、三角形、椭圆、图片
原文:C# Graphic 绘制圆、三角形、椭圆、图片 在form和panel上可以绘制图形,线段,圆,文字,图形等等。 绘制代码必须放在OnPaint()函数里面,因为窗体刷新的时候,都会调用该函数,重新刷新所绘的图。
1511 0
[译] Bob,函数式编程是什么鬼?
本文讲的是[译] Bob,函数式编程是什么鬼?,你懂的。很多人都讨论它。你 Google 一下然后看了看前五篇文章,令人沮丧的是,你发现大部分文章只给出一个含糊不清的 Wikipedia 定义,像是:
992 0
一天编程发现的css名称问题,不支持下划线
Button.roomReadyBtn{ skin: Embed(skinClass='RoomReady_Btn'); } 如果改成RoomReady_Btn,则报错Severity and Description Path Resource Location Creation Time Id{ expected.
601 0
+关注
99
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载