POJ2449 第k最短路径

来源:互联网 发布:社会学stata数据库 编辑:程序博客网 时间:2024/05/22 10:22

  很经典的一道题目,第K最短路,很多应用都会用到的一个小算法。然后解法也很多,这里用了Dijkstra+A*搜索,每次从最小堆中弹出"c[x]+f[x]"值最小的结点x来继续访问,其中c[x]为从起点访问到x点的距离,f[x]为从x点到终点的最短距离。

  不过为了AC这道题目,倒是犯了几个小错误:

  1:根据题目,就算给定的起点s==给定的终点t,那么必须也要走,最短路径不能为0,所以就有了讨论中很多人说的那句代码 if(s==t)k++;

  2:这个错误我也搞不清楚状况,主要是用Dijkstra计算所有点到终点的最短路径时候,我一开始的代码如下,一直是wrong answer。

funcArr[beg-1] = 0;visFlag[beg-1] = true;PriorityQueue<HeapNode> queue = new PriorityQueue<HeapNode>(graph.size(),new Comp1());for(int i=0;i<graph.get(beg-1).lNodes.size();i++){   LinkNode tlNode = graph.get(beg-1).lNodes.get(i);   funcArr[tlNode.lid-1] = tlNode.t;   queue.add(new HeapNode(tlNode.lid, funcArr[tlNode.lid-1]));}

  改为如下就AC了。难道是最近没有常写代码,都愚钝了。

funcArr[beg-1] = 0;PriorityQueue<HeapNode> queue = new PriorityQueue<HeapNode>(graph.size(),new Comp1());queue.add(new HeapNode(beg, 0));

 

  最终AC的完整代码:

import java.util.*;class Node{public Node(){lNodes = new ArrayList<LinkNode>();}public ArrayList<LinkNode> lNodes;}class LinkNode{public LinkNode(){lid = 0;t = 0;}public LinkNode(int linkId, int time){lid = linkId;t = time;}public int lid;public int t;}class HeapNode{public HeapNode(int nid,int cv){this.nodeId = nid;this.cvalue = cv;}public HeapNode(){}public HeapNode(int nid, int cv, int fv){nodeId = nid;cvalue = cv;fvalue = fv;}public int nodeId;public int cvalue;public int fvalue;}class Comp1 implements Comparator<HeapNode>{public int compare(HeapNode arg0, HeapNode arg1) {return arg0.cvalue - arg1.cvalue;}}class Comp2 implements Comparator<HeapNode>{public int compare(HeapNode arg0, HeapNode arg1){return (arg0.cvalue + arg0.fvalue) - (arg1.cvalue + arg1.fvalue); }}public class Main {final static int MAX = 1<<30;public static int[] Dijkstra(ArrayList<Node> graph, int beg){int n = graph.size();int funcArr[] = new int[n];boolean visFlag[] = new boolean[n];for(int i=0;i<n;i++){funcArr[i] = MAX;visFlag[i] = false;}funcArr[beg-1] = 0;PriorityQueue<HeapNode> queue = new PriorityQueue<HeapNode>(graph.size(),new Comp1());queue.add(new HeapNode(beg, 0));while(queue.isEmpty() == false){HeapNode tnode = queue.poll();if(visFlag[tnode.nodeId-1] == true)continue;visFlag[tnode.nodeId-1] = true;for(int i=0;i<graph.get(tnode.nodeId - 1).lNodes.size();i++){LinkNode tlnode = graph.get(tnode.nodeId-1).lNodes.get(i);if(funcArr[tnode.nodeId - 1] + tlnode.t < funcArr[tlnode.lid-1]){funcArr[tlnode.lid-1] = funcArr[tnode.nodeId - 1]  + tlnode.t;queue.add(new HeapNode(tlnode.lid, funcArr[tlnode.lid-1]));}}}return funcArr;}public static int AStartKShortestPath(ArrayList<Node> graph, int beg, int end,int k,int[] funcArr){if(beg==end)k++;int dis = -1;int kcount = 0;int n = graph.size();PriorityQueue<HeapNode> queue = new PriorityQueue<HeapNode>(n,new Comp2());queue.add( new HeapNode(beg,0,funcArr[beg-1]));while(queue.isEmpty() == false){HeapNode hNode= queue.poll();if(hNode.nodeId == end)kcount++;if(kcount == k){//System.out.println(hNode.nodeId+":"+hNode.cvalue+","+hNode.fvalue);dis = hNode.cvalue + hNode.fvalue;break;}for(int i=0;i<graph.get(hNode.nodeId-1).lNodes.size();i++){LinkNode tlNode = graph.get(hNode.nodeId-1).lNodes.get(i);if(funcArr[tlNode.lid-1] < MAX){  HeapNode tmphnode = new HeapNode(tlNode.lid, hNode.cvalue + tlNode.t, funcArr[tlNode.lid-1]);  queue.add(tmphnode);}}}return dis;}public static void main(String[] args){//Initialize the graph and transpose graph//////////////////////Scanner scan = new Scanner(System.in);int n,m;n = scan.nextInt();m = scan.nextInt();ArrayList<Node> graph = new ArrayList<Node>(n);ArrayList<Node> tgraph = new ArrayList<Node>(n);for(int i=0;i<n;i++){graph.add(new Node());tgraph.add(new Node());}for(int i=0;i<m;i++){int b,e,t;b = scan.nextInt();e = scan.nextInt();t = scan.nextInt();//GraphLinkNode tn0 = new LinkNode(e,t);graph.get(b-1).lNodes.add(tn0);//Transpose graphLinkNode tn1 = new LinkNode(b,t);tgraph.get(e-1).lNodes.add(tn1);}int s,t,k;s = scan.nextInt();t = scan.nextInt();k = scan.nextInt();/////////////////////////////////////////////int[] funcArr = Dijkstra(tgraph, t);int dis = AStartKShortestPath(graph, s, t, k, funcArr);System.out.println(dis);}}

原创粉丝点击