题意:
有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;
}