1. 程式人生 > >最短路計數

最短路計數

class sizeof cst get 更新 math truct turn 操作

題目:

  給出一個N個頂點M條邊的無向無權圖,頂點編號為1N。問從頂點1開始,到其他每個點的最短路有幾條。

                                              ——傳送門

受到題解的啟發,用 Dijkstra A掉(手工代碼)

思路:

  1.無向無權圖,建圖的時候別忘記建來回的有向邊

  2.無權,那麽邊長建成1就好了

  3.最短路采用 Dijkstra(堆優化)來做,計數操作改裝進去,tot[1]=1;用 Dijkstra 更新邊長的時候如果大於號(具體見代碼)就覆蓋,相等的話就加上。

AC代碼:

#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<deque>
#include<set>
#include<map>
#include<vector>
#include
<fstream> using namespace std; #define maxn 2000005 #define mod 100003 int head[maxn],vis[maxn],d[maxn],tot[maxn]; int cnt=0,n,m,s; priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q; struct hh { int nex,to; }t[maxn<<1]; inline
void add(int nex,int to) { t[++cnt].nex=head[nex]; t[cnt].to=to; head[nex]=cnt; } inline int read() { char kr=0; char ls; for(;ls>9||ls<0;kr=ls,ls=getchar()); int xs=0; for(;ls>=0&&ls<=9;ls=getchar()) { xs=xs*10+ls-48; } if(kr==-) xs=0-xs; return xs; } inline void dijkstra() { memset(d,0x3f,sizeof(d)); memset(tot,0,sizeof(tot)); memset(vis,0,sizeof(vis)); q.push(make_pair(0,1)); d[1]=0; vis[1]=1; tot[1]=1; while(!q.empty()) { int u=q.top().second; q.pop(); vis[u]=0; for(int v=head[u];v;v=t[v].nex) { if(d[t[v].to]>d[u]+1) { d[t[v].to]=d[u]+1; tot[t[v].to]=tot[u]; if(!vis[v]) { q.push(make_pair(d[t[v].to],t[v].to)); vis[v]=1; } continue; } else if(d[t[v].to]==d[u]+1) { tot[t[v].to]+=tot[u];//tot記錄的是點上的數,不是邊上。(查了好久) tot[t[v].to]%=mod; continue; }//關鍵是這兩個 if 語句,其它的跟單源最短路沒什麽區別 } } } int main() { n=read();m=read(); int x,y; for(int i=1;i<=m;i++) { x=read();y=read(); add(x,y); add(y,x); } dijkstra(); for(int i=1;i<=n;i++) { printf("%d\n",tot[i]); } return 0; }

最短路計數