===== Long slopes ===== **Zadání**\\ Viz odkaz: [[https://cw.felk.cvut.cz/courses/a4b33alg/getdata.php?task=longslopes2&item=descc.html|Dlouhé sjezdovky]].\\ === Nejrychlejší řešení v Javě === import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.StringTokenizer; /** * ====================================================== * ONE END OF THE SLOPE * MAY CONTAIN SEVERAL PATHS DOWNHILL * ====================================================== */ class CheckPoint { ArrayList whereTo; int[] costTo; public CheckPoint(int points) { whereTo = new ArrayList(); costTo = new int[points]; } public void add(int to, int cost) { whereTo.add(to); costTo[to] = cost; } public int costTo(int to) { return costTo[to]; } } // ------------------------------------------------------ /** * ====================================================== * ONE SLOPE - LEADING FROM POINT TO POINT * ====================================================== */ class OneSlope implements Comparable { int from; int to; public OneSlope(int from, int to) { this.from = from; this.to = to; } @Override public int compareTo(OneSlope obj) { return this.from - obj.from; } } //------------------------------------------------------ /** * ====================================================== * SOLVER * - LOADS DATA * - GOES THROUGH THE SLOPES AND FINDS THE BEST ONE(S) * ====================================================== */ class Solver { int points; int slopes; CheckPoint[] allPoints; int[] fromPoint; int[] toPoint; ArrayDeque rFrom; ArrayDeque rTo; int maxLen; public void solve() { loadData(); goThroughSlopes(); printResult(); } private void loadData() { try { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); points = Integer.parseInt(st.nextToken()); slopes = Integer.parseInt(st.nextToken()); allPoints = new CheckPoint[points]; fromPoint = new int[slopes]; toPoint = new int[slopes]; rFrom = new ArrayDeque(); rTo = new ArrayDeque(); maxLen = 0; // Init for (int i = 0; i < points; i++) { allPoints[i] = new CheckPoint(points); } // Load all of the slopes for (int i = 0; i < slopes; i++) { st = new StringTokenizer(br.readLine()); int from = Integer.parseInt(st.nextToken()); int to = Integer.parseInt(st.nextToken()); int cost = Integer.parseInt(st.nextToken()); allPoints[from].add(to, cost); fromPoint[i] = from; toPoint[i] = to; } // Sort slopes from points for better pruning for (int i = 0; i < points; i++) { Collections.sort(allPoints[i].whereTo); } } catch (Exception e) { e.printStackTrace(); } } private void goThroughSlopes() { for (int i = 0; i < slopes; i++) { fixIt(fromPoint[i], toPoint[i]); } } private void fixIt(int from, int to) { int[] arr = new int[to - from]; // First step - go through slopes from starting point for (Integer track : allPoints[from].whereTo) { if (track > to) break; arr[track - from - 1] = allPoints[from].costTo(track); } // Second step - go through points between starting and ending point // and see if there is slope that leads nearer to the ending point // and is longer than the one found earlier in this method for (int i = 0; i < arr.length; i++) { if (arr[i] == 0) continue; for (Integer track : allPoints[i + from + 1].whereTo) { if (track > to) break; int cost = allPoints[i + from + 1].costTo(track) + arr[i]; if (arr[track - from - 1] < cost) arr[track - from - 1] = cost; } } // Compare the length with the best so far found if (arr[arr.length - 1] > maxLen) { rFrom.clear(); rTo.clear(); rFrom.add(from); rTo.add(to); maxLen = arr[arr.length - 1]; } else if (arr[arr.length - 1] == maxLen) { rFrom.add(from); rTo.add(to); } } private void printResult() { ArrayDeque result = new ArrayDeque(); while(!rFrom.isEmpty()) { result.add(new OneSlope(rFrom.pop(), rTo.pop())); } Object[] ar = result.toArray(); Arrays.sort(ar); // Sort the best slopes for (Object sl : ar) { OneSlope os = (OneSlope) sl; System.out.println(os.from + " " + os.to); // print solution } } } //------------------------------------------------------ /** * ====================================================== * MAIN CLASS * CALLS SOLVER TO SOLVE THE PROBLEM * ====================================================== */ public class Main { public static void main(String[] args) { Solver solver = new Solver(); solver.solve(); } } === Nejrychlejší řešení v C/C++ === #include #include typedef struct slopes { int count; short * tos; int * prices; } slopes; typedef struct result { short start; short end; } result; int n, m, max = 0, res_count = 0; slopes **slps; result **res; int **longest_paths; void add_to_res(short start, short end) { if(res_count < 10) { res[res_count]->start = start; res[res_count]->end = end; res_count++; } } int main() { scanf("%i %i", &n, &m); slps = malloc(n*sizeof(slopes*)); res = malloc(10*sizeof(result*)); res[0] = malloc(sizeof(result)); res[1] = malloc(sizeof(result)); res[2] = malloc(sizeof(result)); res[3] = malloc(sizeof(result)); res[4] = malloc(sizeof(result)); res[5] = malloc(sizeof(result)); res[6] = malloc(sizeof(result)); res[7] = malloc(sizeof(result)); res[8] = malloc(sizeof(result)); res[9] = malloc(sizeof(result)); longest_paths = malloc(n*sizeof(int*)); int i, j, k; for(i = 0; icount = 0; slps[i]->tos = malloc((n-i)*sizeof(short)); slps[i]->prices = malloc((n-i)*sizeof(int)); } for(i = 0; itos[slps[a]->count] = b; slps[a]->prices[slps[a]->count] = c; slps[a]->count++; } for(i = n-1; i>=0; i--) { for(j = 0; jcount; j++) { short tmp = slps[i]->tos[j]; if(longest_paths[i][tmp] < slps[i]->prices[j]) longest_paths[i][tmp] = slps[i]->prices[j]; for(k = i; k 0 && slps[i]->prices[j]+longest_paths[tmp][k] > longest_paths[i][k]) { longest_paths[i][k] = slps[i]->prices[j]+longest_paths[tmp][k]; } } } } for(i = 0; icount; j++) { short tmp = slps[i]->tos[j]; int length = longest_paths[i][tmp]; if(length > max) { max = length; res_count = 0; add_to_res(i, tmp); } else if (length == max) { add_to_res(i, tmp); } } } for(i = 0; istart, res[i]->end); } return 0; }