树上的三角形
时间限制: 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
主要算法:
define results
get T
for 1 to T
get N
for 1 to N-1
get 边
getStruct 边s //构造类树
get M
define result
for 1 to M
get S,E
get S,E 到树根的路劲
get S,E 到树根的路劲的非公共节点
get S,E 间的路劲
get values S,E间路劲的段长度集合
sort(values)
result+=Test values //测试是否为三角形
results add result
print results
Test 算法
for i=2 to values.length
if values[i-2]+vaules[i-1]>values[i]
return true
return false
时间限制: 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
主要算法:
define results
get T
for 1 to T
get N
for 1 to N-1
get 边
getStruct 边s //构造类树
get M
define result
for 1 to M
get S,E
get S,E 到树根的路劲
get S,E 到树根的路劲的非公共节点
get S,E 间的路劲
get values S,E间路劲的段长度集合
sort(values)
result+=Test values //测试是否为三角形
results add result
print results
Test 算法
for i=2 to values.length
if values[i-2]+vaules[i-1]>values[i]
return true
return false
程序:
import java.util.*; public class Main { public static void main(String[] args){ Scanner sc=new Scanner(System.in); int T=sc.nextInt(); String[] results=new String[T]; for(int i=0;i<T;i++){ int N=sc.nextInt(); int tempN=N-1; int[][] nodes=new int[tempN][3]; for(int j=0;j<tempN;j++){ nodes[j][0]=sc.nextInt(); nodes[j][1]=sc.nextInt(); nodes[j][2]=sc.nextInt(); } List<ArrayList<Integer>> struct=getStruct(nodes); int M=sc.nextInt(); String result=""; for(int j=0;j<M;j++){ int start=sc.nextInt(); int end=sc.nextInt(); result=result+" "+getResult(start,end,struct,nodes); } results[i]=result.trim(); } printResult(results); } private static List<ArrayList<Integer>> getStruct(int[][] nodes) { ArrayList<Integer> num01s=new ArrayList<Integer>(nodes.length); int[] temp=new int[nodes.length+1]; for(int i=0;i<temp.length;i++){ temp[i]=0; } for(int i=0;i<nodes.length;i++){ temp[(nodes[i][0]-1)]++; temp[(nodes[i][1]-1)]++; } for(int i=0;i<temp.length;i++){ if(temp[i]==1) num01s.add(i+1); } int structLength=num01s.size()-1; List<ArrayList<Integer>> struct=new ArrayList<ArrayList<Integer>>(structLength); boolean[] flags=new boolean[structLength+1]; for(int i=0;i<flags.length;i++){ flags[i]=true; } List<Integer> success=new ArrayList<Integer>(nodes.length+1); for(int i=0;i<structLength;i++){ ArrayList<Integer> list=new ArrayList<Integer>(nodes.length+1); for(int j=0;j<flags.length;j++){ if(flags[j]){ flags[j]=false; list.add(num01s.get(j)); success.add(num01s.get(j)); break; } } int node=list.get(0); boolean flag=true; while(flag){ for(int k=0;k<nodes.length;k++){ if((node==nodes[k][0])&&(!success.contains(nodes[k][1]))){ list.add(nodes[k][1]); node=nodes[k][1]; success.add(node); break; }else if((node==nodes[k][1])&&(!success.contains(nodes[k][0]))){ list.add(nodes[k][0]); node=nodes[k][0]; success.add(node); break; } } if(i!=0){ int add=list.get(list.size()-1); for(int suc:success){ for(int j=0;j<nodes.length;j++){ if((suc==nodes[j][0] && add==nodes[j][1])||(suc==nodes[j][1] && add==nodes[j][0])){ if(!list.contains(suc)){ list.add(suc); flag=false; list=swap(list); break; } } } } } if(num01s.contains(node)){ flags[num01s.indexOf(node)]=false; flag=false; } } struct.add(list); } return struct; } private static ArrayList<Integer> swap(ArrayList<Integer> list) { ArrayList<Integer> temp=new ArrayList<Integer>(list.size()); for(int i=list.size()-1;i>=0;i--){ temp.add(list.get(i)); } return temp; } private static String getResult(int start, int end, List<ArrayList<Integer>> struct, int[][] nodes) { ArrayList<Integer> startPath=getNodePath(start,struct); ArrayList<Integer> endPath=getNodePath(end,struct); ArrayList<Integer> SE=new ArrayList<Integer>(nodes.length+1); int common=getCommonNode(startPath,endPath); if(startPath.indexOf(common)==0){ SE=getPath(common,endPath); }else if( endPath.indexOf(common)==0){ SE=getPath(common,startPath); }else { SE=getPath(common,startPath,endPath); } int[] values=getValue(SE,nodes); sort(values); return echo(values); } private static ArrayList<Integer> getPath(int common, ArrayList<Integer> list) { ArrayList<Integer> l=new ArrayList<Integer>(list.size()); int n=list.indexOf(common); for(int i=0;i<=n;i++){ l.add(list.get(i)); } return l; } private static void sort(int[] values) { for(int i=0;i<values.length;i++){ int min=i; for(int j=i+1;j<values.length;j++){ if(values[j]<values[min]) min=j; } if(i!=min){ int temp=values[i]; values[i]=values[min]; values[min]=temp; } } } private static String echo(int[] values) { if(values.length<3) return "No"; String result="No"; for(int i=2;i<values.length;i++){ if(judge(values[i-2],values[i-1],values[i])){ result="Yes"; break; } } return result; } private static boolean judge(int i, int j, int k) { return ((i+j)>k); } private static int[] getValue(ArrayList<Integer> sE,int[][] nodes) { int[] values=new int[sE.size()-1]; for(int i=0;i<values.length;i++){ for(int j=0;j<nodes.length;j++){ int x=sE.get(i); int y=sE.get(i+1); if(nodes[j][0]==x && nodes[j][1]==y){ values[i]=nodes[j][2]; break; }else if (nodes[j][1]==x && nodes[j][0]==y){ values[i]=nodes[j][2]; break; } } } return values; } private static ArrayList<Integer> getPath(int m, ArrayList<Integer> xList, ArrayList<Integer> yList) { ArrayList<Integer> path=new ArrayList<Integer>(xList.size()+yList.size()); int xindex=xList.indexOf(m); int yindex=yList.indexOf(m); for(int i=0;i<xindex;i++){ path.add(xList.get(i)); } for(int i=yindex;i>=0;i--){ path.add(yList.get(i)); } return path; } private static int getCommonNode(ArrayList<Integer> xList, ArrayList<Integer> yList) { int max=xList.size(); int c=-1; for(int i=0;i<max;i++){ int temp=xList.get(i); if(yList.contains(temp)){ c=temp; break; } } return c; } private static ArrayList<Integer> getNodePath(int start, List<ArrayList<Integer>> struct) { ArrayList<Integer> temp=new ArrayList<Integer>(); temp.add(start); int s=start; int head=struct.get(0).get(0); int slength=struct.size(); boolean flag=true; while(flag){ for(int i=0;i<slength;i++){ if(struct.get(i).contains(s) && s!=struct.get(i).get(0)){ int x=struct.get(i).indexOf(s); for(int j=(x-1);j>=0;j--){ temp.add(struct.get(i).get(j)); } s=struct.get(i).get(0); break; } } if(head==s){ flag=false; } } return temp; } private static void printResult(String[] result) { for(int i=0;i<result.length;i++){ System.out.println("Case #"+(i+1)+":"); String[] words=result[i].split(" "); for(String word:words) System.out.println(word); } } }
这也是同样了,通过了比赛系统小数据测试,大数据测试未知。
——20130408
PS:
今天早晨数据出来了,这道题的大数据测试时TLE,超时。在情理之中。原因见博文《2013编程之美资格赛之大数据测试(Java实现)》
——20130409