山东省第七届ACM大学生程序设计竞赛 C题 Proxy 最短路板子题

题意:

有n+1个服务器(1,2,3…..n,n+1),你的电脑是0,问你从0到n+1的最短路的第一个服务器是哪个,如果可以直接到,并且路径最短输出0,如果到达不了输出-1;

分析:

典型的最短路板子题,用的是刘汝佳的紫皮书的算法,稍微改动了几个地方,自己并不是很熟悉这个算法,修改了很多遍;
其中d[0]表示0是否被访问过,p[0]表示的是最短路的第一个节点,s表示的是一共有多少个节点。理解可能会有一些问题,要是有问题,帮忙指正,非常感谢,如果要是有人能推荐一下这个算法的详细解释,十分感谢,^_^

代码:

#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;
}

猜你喜欢

转载自blog.csdn.net/shensiback/article/details/80166980