dijkstra (优先队列优化)
找一个无向图到一点最短距离为l的点的个数(该点可以在边上)
分在点上和边上2种进行计数, 在边上的则要对该边的2个顶点讨论一下
//单源最短路 #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <queue> using namespace std; const int maxn=100000+123; const int inf=0x5fffffff; struct Edge{ int v, w, next; }edge[maxn*2]; int head[maxn], cnt; struct Node{ int u, w; bool operator < (Node a)const { return w > a.w; } }; void addedge(int u, int v, int w) { edge[cnt].v=v; edge[cnt].w=w; edge[cnt].next=head[u]; head[u]=cnt++; } int dist[maxn]; void Dijkstra(int s, int n)//0到n-1 s是源点 { for (int i=0; i<n; ++i) dist[i]=inf; dist[s]=0; priority_queue<Node> q; Node cur; cur.u=s; cur.w=0; q.push(cur); while (!q.empty()) { cur=q.top(); q.pop(); if(dist[cur.u]<cur.w)continue; for (int p=head[cur.u]; ~p; p=edge[p].next) if(dist[edge[p].v]>dist[cur.u]+edge[p].w) { dist[edge[p].v]=dist[cur.u]+edge[p].w; Node tmp; tmp.u=edge[p].v; tmp.w=dist[edge[p].v]; q.push(tmp); } } //for (int i=0; i<n; ++i)cout << dist[i] << " "; //cout << endl; } void init () { cnt=0; memset (head, -1, sizeof(head)); } void solve() { init(); int n, m, s, u, v, w, l; cin >> n >> m >>s; s--; for (int i=0; i<m; ++i) { cin >> u >> v >> w; u--, v--; addedge(u, v, w); addedge(v, u, w); } cin >> l; Dijkstra(s, n); int ans=0; for (int i=0; i<n; ++i)if(dist[i]==l)ans++; for (int i=0; i<cnt; i+=2) { w=edge[i].w; u=edge[i].v; v=edge[i^1].v; if(dist[u]>dist[v])u^=v^=u^=v; if(dist[u]<l && dist[v]>=l && dist[u]+w>l)ans++; if(dist[u]<l && dist[v]<l && (dist[u]+dist[v]+w)>(2*l) )ans+=2; if(dist[u]<l && dist[v]<l && (dist[u]+dist[v]+w) == (2*l) )ans++; } printf("%d\n", ans); } int main () { solve(); return 0; }