Dijkstra的Shortest Path-HackerRank

时间:2016-10-20 10:07:03

标签: algorithm graph graph-algorithm shortest-path dijkstra

我正在解决问题 - Dijkstra的最短距离2.这是一个link

给定由N个节点(标记为1到N)组成的图,其中特定给定节点S表示起始位置S并且两个节点之间的边缘具有给定长度,其可以或可以不等于其中的其他长度。曲线图。

需要计算从起始位置(节点S)到图中所有其他节点的最短距离。

注意:如果节点无法访问,则距离假定为-1。

输入格式

第一行包含,表示测试用例的数量。 每个测试用例的第一行有两个整数,表示图中的节点数,并表示图中边的数量。

下一行每个由三个以空格分隔的整数组成,其中和表示存在无向边的两个节点,表示这些相应节点之间的边长。

最后一行有一个整数,表示起始位置。

约束

如果同一对节点之间有不同权重的边缘,则它们应被视为原样,就像多个边缘一样。

输出格式

对于每个测试用例,打印一行包含空格分隔的整数,表示节点的最短距离,而不是从起始位置开始按照标签的递增顺序。

对于无法访问的节点,请打印。

示例输入

24 3 15

示例输出

class Node implements Comparator<Node>{
     int cost, node;
     Node(){}
     Node(int node, int cost){
        this.node=node;
        this.cost=cost;
    }
@Override
public int compare(Node n1, Node n2){
    if(n1.cost<n2.cost)return -1;
    else if(n1.cost>n2.cost)return 1;
    return 0;
  }
 }
 class Solution {
 // Working program using Reader Class
 static int adjmatrix[][];
 static PriorityQueue<Node> pq;
 static boolean visited[];
 static int distance[];
 @SuppressWarnings("unchecked")
 static ArrayList<Map<Integer,Integer>> list;


     static class Reader
     {
         final private int BUFFER_SIZE = 1 << 16;
         private DataInputStream din;
         private byte[] buffer;
         private int bufferPointer, bytesRead;

         public Reader()
         {
             din = new DataInputStream(System.in);
             buffer = new byte[BUFFER_SIZE];
             bufferPointer = bytesRead = 0;
         }

         public Reader(String file_name) throws IOException
         {
             din = new DataInputStream(new FileInputStream(file_name));
             buffer = new byte[BUFFER_SIZE];
             bufferPointer = bytesRead = 0;
         }

         public String readLine() throws IOException
         {
             byte[] buf = new byte[64]; // line length
             int cnt = 0, c;
             while ((c = read()) != -1)
             {
                 if (c == '\n')
                     break;
                 buf[cnt++] = (byte) c;
             }
             return new String(buf, 0, cnt);
         }

         public int nextInt() throws IOException
         {
             int ret = 0;
             byte c = read();
             while (c <= ' ')
                 c = read();
             boolean neg = (c == '-');
             if (neg)
                 c = read();
             do
             {
                 ret = ret * 10 + c - '0';
             }  while ((c = read()) >= '0' && c <= '9');

             if (neg)
                 return -ret;
             return ret;
         }

         public long nextLong() throws IOException
         {
             long ret = 0;
             byte c = read();
             while (c <= ' ')
                 c = read();
             boolean neg = (c == '-');
             if (neg)
                 c = read();
             do {
                 ret = ret * 10 + c - '0';
             }
             while ((c = read()) >= '0' && c <= '9');
             if (neg)
                 return -ret;
             return ret;
         }

         public double nextDouble() throws IOException
         {
             double ret = 0, div = 1;
             byte c = read();
             while (c <= ' ')
                 c = read();
             boolean neg = (c == '-');
             if (neg)
                 c = read();

             do {
                 ret = ret * 10 + c - '0';
             }
             while ((c = read()) >= '0' && c <= '9');

             if (c == '.')
             {
                 while ((c = read()) >= '0' && c <= '9')
                 {
                     ret += (c - '0') / (div *= 10);
                 }
             }

             if (neg)
                 return -ret;
             return ret;
         }

         private void fillBuffer() throws IOException
         {
             bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
             if (bytesRead == -1)
                 buffer[0] = -1;
         }

         private byte read() throws IOException
         {
             if (bufferPointer == bytesRead)
                 fillBuffer();
             return buffer[bufferPointer++];
         }

         public void close() throws IOException
         {
             if (din == null)
                 return;
             din.close();
         }
     }
    ////////////////////////////////////////////////
     public static void initialize(int n){
        // adjmatrix=new int[n+1][n+1];
         visited=new boolean[n+1];
         distance=new int[n+1];
         list=new ArrayList<>(n+1);
         pq=new PriorityQueue<>(new Node());
         for(int i=0; i<n+1; ++i)distance[i]=Integer.MAX_VALUE;
     }

 //////////////////////////////////////////////
public static void shortestPath(int s){
   // int length=adjmatrix.length;
    int min_node;
    visited[s]=true;
    distance[s]=0;
    pq.add(new Node(s,0));
    while(!pq.isEmpty()){
        min_node=pq.remove().node;
        visited[min_node]=true;
        updateDistance(min_node);
    }
}
///////////////////////////////////////////////
 //Using adjlist
private static void updateDistance(int s){
    Map<Integer,Integer> current=list.get(s);
   // Iterator itr=current.entrySet().iterator();
   for(Map.Entry<Integer, Integer> entry:current.entrySet()){
        int node=entry.getKey();
        int cost=entry.getValue();
        if(!visited[node]){

                distance[node]=Math.min(cost+distance[s], distance[node]);
                pq.add(new Node(node,distance[node]));

        }
    }

}

 ////////////////////////////////////////////////////////////////
     public static void main(String []args)throws IOException{
         Reader r=new Reader();
     //StringBuilder sb = new StringBuilder();


     int T=r.nextInt(), N, M;
     for(int caseNo=1; caseNo<=T; ++caseNo){
         N=r.nextInt();
         //initialization
         initialize(N);
         //initialization of adjacecny matrix



         M=r.nextInt();
         //list=new ArrayList<>(N+1);
        for(int i=1; i<=N+1; ++i)list.add(new HashMap<Integer, Integer>());

         for(int j=1; j<=M; ++j){

                 int node1=r.nextInt();
                 int node2=r.nextInt();
                 int distance=r.nextInt();

                 if(list.get(node1).get(node2)!=null){
                     int temp=list.get(node1).get(node2);
                     if(temp<distance)continue;
                 }

                 list.get(node1).put(node2,distance);
                 list.get(node2).put(node1, distance);

         }

         //end of graph initialization as a hybrid of adjmatrix and adjlist

        int s=r.nextInt();
         shortestPath(s);

         for(int i=1; i<=N; ++i)if(i!=s)System.out.print(((distance[i]==Integer.MAX_VALUE)?-1:distance[i])+" ");
         System.out.println();
     }//end of test cases loop[
 }
 }

这是我的代码:

Node类

select * from transposed_table order by value_column desc limit 5

我为长代码和问题道歉。我的程序仅适用于示例测试用例。在其余部分,它正确地开始,但在输入结束时它最终会给出不同的答案。如果需要,我可以粘贴预期输入和输出的副本。据我所知,这可能与我如何处理多个无向边的情况​​有关。我只是保持较小的优势。

P.S.-它现在给出正确的值,但速度不够快。欢迎任何优化建议

1 个答案:

答案 0 :(得分:0)

乍一看,您的代码似乎是正确的(虽然我不是Java专家)。

以下是我的代码作为参考(可能会给你一个想法),&amp;这是我的github中代码的链接 Dijkstra hackerrank

实际上它已被Queue版本接受(你不必用minHeap实现它 - 尽管minHeap版本更正确 - O(E log V)而不是O(V ^ 2)。

这是队列版本: Dijkstra queue version

#include <iostream>
#include <vector>
#include <utility>
#include <limits>
#include <memory>
#include <map>
#include <set>
#include <queue>
#include <stdio.h>


using namespace std;
using vi = vector<int>;
using ii = pair<int, int>;
using vii = vector<ii>;
const int max_int = 1 << 20; //numeric_limits<int>::max();


class Graph{
public:
    Graph(int nodes = 3000, int edges = 3000*3000/2):
        nodes_(nodes+1),
        edges_(edges),
        dist_(nodes+1, max_int),
        adjList_(nodes+1),
        in_queue_(nodes+1, 0)
    {
    }
    ~Graph() {}
    void addEdge(int from, int to, int w) {

        adjList_[from].emplace_back(ii(w, to));
        adjList_[to].emplace_back(ii(w, from));
    }
    vii getNeighbours(int n) {
        return adjList_[n];
    }
    void dijkstra(int src);

private:
    vi dist_;
    vector<vii> adjList_;
    int nodes_;
    int edges_;
    int src_;
    void print(int node);
    vi in_queue_;
   // queue<int> q_;
    std::priority_queue<ii, vii, greater<ii>> q_;
};

void Graph::dijkstra(int src)
{
    src_ = src;
    dist_[src] = 0;
    q_.push(make_pair(0, src)); in_queue_[src_] = 1;
    while(!q_.empty()) {
        auto front = q_.top();  q_.pop();
        int d = dist_[front.second], u = front.second;
        in_queue_[u] = 0;
            for(int i = 0 ; i < (int)adjList_[u].size(); ++i) {
                auto v = adjList_[u][i];
                if(dist_[v.second] > dist_[u] + v.first) {
                    dist_[v.second] = dist_[u] + v.first;
                    if(!in_queue_[v.second]) {
                        q_.push(make_pair(dist_[v.second], v.second));
                        in_queue_[v.second] = 1;
                    }
                }
            }
    }

    for(int i = 1; i < nodes_; ++i) {
        if(i == src_) {
            continue;
        }
        if(dist_[i] == max_int) {
            cout << "-1" << " ";
        }
        else{
            cout << dist_[i] << " ";
        }
    }
    cout << endl;
}



int main(){
     std::ios::sync_with_stdio(false); 
    int t;
    cin >> t;
    for(int a0 = 0; a0 < t; a0++){
        int n;
        int m;
        cin >> n >> m;
        unique_ptr<Graph> g(new Graph(n,m));
        for(int a1 = 0; a1 < m; a1++){
            int x;
            int y;
            int r;

            cin >> x >> y >> r;
            g->addEdge(x, y, r);
        }
        int s;
        cin >> s;
        //scanf("%d", &s);
        g->dijkstra(s);
    }
    return 0;
}