The 7th ACM College Student Programming Contest in Shandong Province C question Proxy shortest board question

Title:

There are n+1 servers (1,2,3…..n,n+1), your computer is 0, ask you which is the first server with the shortest path from 0 to n+1, if you can directly to, and the shortest path outputs 0, if it cannot be reached, output -1;

analyze:

The typical shortest board sub-question uses the algorithm of Liu Rujia's Purple Book, with a few slight changes. I am not very familiar with this algorithm, and I have revised it many times;
d[0] indicates whether 0 has been accessed, p[0] represents the first node with the shortest path, and s represents the total number of nodes. There may be some problems in understanding. If there are problems, please help to correct them. Thank you very much. If anyone can recommend a detailed explanation of this algorithm, I would be very grateful. ^_^

Code:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <set>
#include <algorithm>
#include <queue>
#include <map>
#define debug cout<<"******"<<endl;
#define ll long long;
using namespace std;
const int maxn = 1005;
const int INF = 0x3f3f3f3f;
const int mod = 1e9+7;
int n;
struct Edge{
    int from,to,dist;
    Edge(int u,int v,int d):from(u),to(v),dist(d){}
};
struct HeapNode{
    int d,u;
    HeapNode(int td,int tu) : d(td) , u(tu) { }
    bool operator < (const HeapNode& rhs) const{
        return d > rhs.d;
    }
};
struct Dijkstra{
    int m;
    vector<Edge> edges;
    vector<int> G[maxn];
    bool done[maxn];
    int d[maxn];
    int p[maxn];
    void init(){
        for(int i = 0; i <= n+1;i++){
            G[i].clear();
        }
        edges.clear();
    }
    void AddEdge(int from,int to,int dist){
        edges.push_back(Edge(from,to,dist));
        m = edges.size();
        G[from].push_back(m-1);
    }
    void dijkstra(int s){
        priority_queue <HeapNode> Q;
        for(int i = 0; i <= n+1; i++){
            d[i] = INF;
        }
        d[s] = 0;
        memset(done,0,sizeof(done));
        Q.push(HeapNode(0,s));
        while(!Q.empty()){
            HeapNode x = Q.top();Q.pop();
            int u = x.u;
            if(done[u]) continue;
            done[u] = true;
            for(int i = 0; i < G[u].size();i++){
                Edge &e = edges[G[u][i]];
                if(d[e.to] >= d[u] + e.dist){
                    d[e.to] = d[u] + e.dist;
                    p[e.to] = u;
                    Q.push(HeapNode(d[e.to],e.to));
                }else if(d[e.to] == d[u] + e.dist){
                    p[e.to] = min(G[u][i], p[e.to]);
                }
            }
        }
    }
}D;
int main(){
    std::ios::sync_with_stdio(false);
    int T,m;cin>>T;
    while(T--){
        D.init();
        cin>>n>>m;
        int u,v,w;
        for(int i = 0; i < m;i++){
            cin>>u>>v>>w;
            D.AddEdge(v,u,w);
        }
        D.dijkstra(n+1);

        if(D.d[0] >= INF){
            cout<<-1<<endl;
        }
        else if(D.p[0] == n+1){
            cout<<0<<endl;
        }else{
            cout<<D.p[0]<<endl;
        }
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325401945&siteId=291194637