我正在解决问题 - 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.-它现在给出正确的值,但速度不够快。欢迎任何优化建议
答案 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;
}