標籤:提高 site this 根據 資料 接下來 筆記 空格 images
目錄
1 問題描述
2 解決方案
1 問題描述問題描述
農夫約翰正在針對一個新地區的牛奶配送合約進行研究。他打算分發牛奶到T個城鎮(標號為1..T),這些城鎮通過R條標號為(1..R)的道路和P條標號為(1..P)的航路相連。
每一條公路i或者航路i表示成串連城鎮Ai(1<=A_i<=T)和Bi(1<=Bi<=T)代價為Ci。每一條公路,Ci的範圍為0<=Ci<=10,000;由於奇怪的運營策略,每一條航路的Ci可能為負的,也就是-10,000<=Ci<=10,000。
每一條公路都是雙向的,正向和反向的花費是一樣的,都是非負的。
每一條航路都根據輸入的Ai和Bi進行從Ai->Bi的單向通行。實際上,如果現在有一條航路是從Ai到Bi的話,那麼意味著肯定沒有通行方案從Bi回到Ai。
農夫約翰想把他那優良的牛奶從配送中心送到各個城鎮,當然希望代價越小越好,你可以協助他嘛?配送中心位於城鎮S中(1<=S<=T)。
輸入格式
輸入的第一行包含四個用空格隔開的整數T,R,P,S。
接下來R行,描述公路資訊,每行包含三個整數,分別表示Ai,Bi和Ci。
接下來P行,描述航路資訊,每行包含三個整數,分別表示Ai,Bi和Ci。
輸出格式輸出T行,分別表示從城鎮S到每個城市的最小花費,如果到不了的話輸出NO PATH。範例輸入6 3 3 4
1 2 5
3 4 5
5 6 10
3 5 -100
4 6 -100
1 3 -10範例輸出NO PATH
NO PATH
5
0
-95
-100資料規模與約定
對於20%的資料,T<=100,R<=500,P<=500;
對於30%的資料,R<=1000,R<=10000,P<=3000;
對於100%的資料,1<=T<=25000,1<=R<=50000,1<=P<=50000。
2 解決方案
本題主要考查最短路徑,其中時間效率最好的演算法為SPFA演算法,但是下面的代碼在藍橋系統中評分為30或者35分,原因:運行逾時,而同樣的方法,用C來實現在藍橋系統中評分為95或者100分,用C實現的代碼請見文末參考資料1。
如果有哪位同學Java版本代碼測評分數超過50分的同學,還望借鑒一下代碼,不甚感激~
具體代碼如下:
import java.util.ArrayList;import java.util.Scanner;public class Main { public static int T, R, P, S; public static ArrayList<edge>[] map; public static int[] distance; static class edge { public int a; //邊的起點 public int b; //邊的終點 public int v; //邊的權值 public edge(int a, int b, int v) { this.a = a; this.b = b; this.v = v; } } @SuppressWarnings("unchecked") public void init() { map = new ArrayList[T + 1]; distance = new int[T + 1]; for(int i = 0;i <= T;i++) { map[i] = new ArrayList<edge>(); distance[i] = Integer.MAX_VALUE; } } public void spfa() { ArrayList<Integer> town = new ArrayList<Integer>(); distance[S] = 0; town.add(S); int[] count = new int[T + 1]; boolean[] visited = new boolean[T + 1]; count[S]++; visited[S] = true; while(town.size() != 0) { int start = town.get(0); town.remove(0); visited[start] = false; for(int i = 0;i < map[start].size();i++) { edge to = map[start].get(i); if(distance[to.b] > distance[start] + to.v) { distance[to.b] = distance[start] + to.v; if(!visited[to.b]) { town.add(to.b); visited[to.b] = true; count[to.b]++; if(count[to.b] > T) //此時有負環出現 return; } } } } } public void getResult() { spfa(); for(int i = 1;i <= T;i++) { if(distance[i] == Integer.MAX_VALUE) System.out.println("NO PATH"); else System.out.println(distance[i]); } } public static void main(String[] args) { Main test = new Main(); Scanner in = new Scanner(System.in); T = in.nextInt(); R = in.nextInt(); P = in.nextInt(); S = in.nextInt(); test.init(); for(int i = 1;i <= R;i++) { int a = in.nextInt(); int b = in.nextInt(); int v = in.nextInt(); map[a].add(new edge(a, b, v)); map[b].add(new edge(b, a, v)); } for(int i = 1;i <= P;i++) { int a = in.nextInt(); int b = in.nextInt(); int v = in.nextInt(); map[a].add(new edge(a, b, v)); } test.getResult(); }}
參考資料:
1. 藍橋杯 演算法提高 道路和航路 滿分AC ,SPFA演算法的SLF最佳化,測試資料還是比較水的,貌似沒有重邊
演算法筆記_165:演算法提高 道路和航路(Java)