#include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; const int INF = 1000000000; const int maxn = 4000 + 10; struct Edge { int from, to, dist, val; }; struct HeapNode { int d, u; bool operator < (const HeapNode& rhs) const { return d > rhs.d; } }; struct Dijkstra { int n, m; vector<Edge> edges; vector<int> G[maxn]; bool done[maxn]; // 是否已永久标号 int d[maxn]; // s到各个点的距离 int p[maxn]; // 最短路中的上一条弧 void init(int n) { this->n = n; for(int i = 0; i < n; i++) G[i].clear(); edges.clear(); } void AddEdge(int from, int to, int dist, int val) { edges.push_back((Edge){from, to, dist, val}); m = edges.size(); G[from].push_back(m-1); } void dijkstra(int s) { priority_queue<HeapNode> Q; for(int i = 0; i < n; 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] = G[u][i]; Q.push((HeapNode){d[e.to], e.to}); } } } } vector<int> GetShortestPath(int s, int t) { vector<int> path; while(t != s) { path.push_back(edges[p[t]].val); t = edges[p[t]].from; } reverse(path.begin(), path.end()); return path; } };
时间复杂度O((m + n)log n),
图中节点编号得从0开始,邻接表储存,所以不用判重,如果是无向图,每条无向边需调用两次AddEdge
#include <iostream> #include <cstring> #include <cstdio> #include <string> #include <algorithm> #include <map> #include <vector> #include<queue> using namespace std; typedef long long LL; typedef pair<int,int> P; const int maxn = 10000 + 5; const int INF = 1000000000; struct Edge{ int from,to,dis; Edge(int from,int to,int dis){ this -> from = from; this -> to = to; this -> dis = dis; } }; int d[maxn]; int vis[maxn]; vector<Edge> G[maxn]; void Dij(int x,int n){ priority_queue<P,vector<P>,greater<P> > Q; memset(vis,0,sizeof(vis)); for(int i = 0;i <= n;i++) d[i] = INF; Q.push(P(0,x)); while(!Q.empty()){ P p = Q.top();Q.pop(); int id = p.second; int dis = p.first; if(vis[id] == 1) continue; vis[id] = 1; d[id] = dis; for(int i = 0;i < G[id].size();i++){ Edge edgs = G[id][i]; int to = edgs.to; int der = edgs.dis; if(d[to] > d[id] + der){ d[to] = d[id] + der; Q.push(P(d[to],to)); } } } } int main(){ int t,kase = 0; scanf("%d",&t); while(t--){ int n,m; kase++; for(int i = 0;i < maxn;i++) G[i].clear(); scanf("%d%d",&n,&m); for(int i = 1;i <= n;i++){ int x;scanf("%d",&x); G[0].push_back(Edge(0,i,x)); } while(m--){ int a,b,c1,c2; scanf("%d%d%d%d",&a,&b,&c1,&c2);a++;b++; G[a].push_back(Edge(a,b,c1)); G[b].push_back(Edge(b,a,c2)); } Dij(0,n); int ans = 0,ansx; for(int i = 1;i <= n;i++){ if(d[i] > ans){ ans = d[i]; ansx = i-1; } } printf("Scenario #%d:\n",kase); printf("%d\n",ansx); printf("\n"); } return 0; }