最短路徑樹
阿新 • • 發佈:2020-12-04
最短路徑樹
Define
最短路徑樹即為由一個給定的點出發,到每一個點的最短路徑所構成的一棵樹
求法
在圖中設定一個根節點,進行一遍 dijkstra ,在過程中就可以處理出它的一棵最短路徑樹
例題
本題只需求得所用的最短路徑樹的數量即可
code
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<math.h> #include<vector> #include<queue> #define ll long long const ll mod=2147483647ll; const ll maxn=1e3+10; ll n,m,tot,ans=1; ll head[maxn*maxn],dis[maxn],vis[maxn],num[maxn]; struct node { ll u,v,w,nxt; }s[maxn*maxn]; inline void add(ll u,ll v,ll w) { s[++tot].v=v; s[tot].w=w; s[tot].nxt=head[u]; head[u]=tot; } inline void dij(ll x) { std::priority_queue<std::pair<ll,ll> > q; memset(dis,0x3f,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[x]=0; q.push(std::make_pair(-dis[x],x)); while(q.size()) { ll u=q.top().second; q.pop(); if(vis[u]) continue; vis[u]=1; for(int i=head[u];i;i=s[i].nxt) { ll v=s[i].v; ll w=s[i].w; if(dis[v]>dis[u]+w) { dis[v]=dis[u]+w; if(!vis[v]) { q.push(std::make_pair(-dis[v],v)); } } } } } int main(void) { scanf("%lld %lld",&n,&m); for(int i=1;i<=m;i++) { ll x,y,z; scanf("%lld %lld %lld",&x,&y,&z); add(x,y,z); add(y,x,z); } dij(1); for(int i=1;i<=n;i++) { for(int j=head[i];j;j=s[j].nxt) { ll v=s[j].v; ll w=s[j].w; if(dis[v]==dis[i]+w) { num[v]++; } } } for(int i=1;i<=n;i++) { if(num[i]) ans=ans*num[i]%mod; } printf("%lld\n",ans); return 0; }