洛谷1144 最短路的個數
阿新 • • 發佈:2018-12-24
方法一:這種發放適合於只求最短路的個數,不能用來輸出最短路。
我們直接在spfa的過程中使用cnt[]陣列記錄最短路的個數,用dijkstra也可以!
更新cnt分情況:
- 如果dis[next]>dis[now]+1
那麼之前到達點next的路>dis[now]+1
cnt[next]=cnt[now] - 如果dis[next]==dis[now]+1
那麼之前到達點next的路也有距離為dis[now]+1的點。
cnt[next]+=cnt[now]
#include <bits/stdc++.h> using namespace std; #define ll long long #define inf 0x3f3f3f3f #define res register int const int maxn=1e6+5; vector<int> v[maxn]; int dis[maxn],vis[maxn]; int cnt[maxn]; int N,M,mod=100003; //最短路的個數 void spfa() { memset(dis,inf,sizeof(dis)); memset(vis,0,sizeof(vis)); queue<int> q; q.push(1); vis[1]=1; dis[1]=0; cnt[1]=1; while(!q.empty()){ int x=q.front(); q.pop(); vis[x]=0; for(res i=0;i<v[x].size();i++){ int y=v[x][i]; if(dis[y]>dis[x]+1){ dis[y]=dis[x]+1; cnt[y]=cnt[x]%mod; if(!vis[y]){ q.push(y); vis[y]=1; } }else if(dis[y]==dis[x]+1){ cnt[y]+=cnt[x]; cnt[y]%=mod; if(!vis[y]){ q.push(y); vis[y]=1; } } } } } int main() { scanf("%d%d",&N,&M); int from,to; for(res i=0;i<M;i++){ scanf("%d%d",&from,&to); v[from].push_back(to); v[to].push_back(from); } spfa(); for(res i=1;i<=N;i++){ printf("%d",cnt[i]); printf("\n"); } return 0; }
方法二:可以記錄路徑,但是很慢
我們可以用vector<int> pre[maxn]記錄下每一個節點被最短到達的前一個點的節點序號。因為我們記錄的都是前驅,所以我們可以從終點出發。這樣遍歷到的每一個節點都在最短路上面。然後我們dfs或者bfs,ans+每一個遍歷到節點前驅的個數-1。最後輸出讓ans+1。