題目意思是找在圖中與原點距離為L的點的個數,這些點可以在圖中的點上,也可以在邊上。
先用dijkstra求出原點到各個點的最短距離,然後先掃一遍點,加上距離為L的點,再掃一遍邊,分幾種情況去判斷在邊上能有幾個合格點(1個或2個),這裡寫的時候仔細點就可以了。
#include<cstdio>#include<cstring>#include<queue>#include<algorithm>#include <iostream>#include<cmath>using namespace std;const int INF = 1000000000;const int maxn = 100000 + 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; }};Dijkstra solver;struct Node{ int from,to,dis;};vector<Node> edg;int main(){ int n,m,s,l; while(cin >> n >> m >> s){ s--; solver.init(n); edg.clear(); for(int i = 0;i < m;i++){ int v,u,w; cin >> v >> u >> w; v--;u--; edg.push_back(Node{v,u,w}); solver.AddEdge(v,u,w,0); solver.AddEdge(u,v,w,0); } cin >> l; solver.dijkstra(s); int ans = 0; for(int i = 0;i < n;i++){ if(solver.d[i] == l) ans++; } for(int i = 0;i < edg.size();i++){ int x = solver.d[edg[i].from]; int y = solver.d[edg[i].to]; if(x > y) swap(x,y); int dis = edg[i].dis; if(x + dis < y && x + dis >= l){ if(x < l ) ans++; if(y < l) ans++; } else if(x + dis == y && y != l && x + dis >= l){ if(x < l ) ans++; if(y < l ) ans++; } else if((x+dis > y) && ((x+y+dis)*1.0/2 > l)){ if(x < l ) ans++; if(y < l ) ans++; } else if((x+dis > y) && (fabs(((x+y+dis)*1.0/2) - l) <1e-6) && x < l){ ans++; } } cout << ans << endl; } return 0;}