洛谷 P1144 最短路計數 解題報告
阿新 • • 發佈:2018-07-01
++ 報告 CA amp ret 正整數 std 最短路 www
P1144 最短路計數
題目描述
給出一個\(N\)個頂點\(M\)條邊的無向無權圖,頂點編號為\(1-N\)。問從頂點1開始,到其他每個點的最短路有幾條。
輸入輸出格式
輸入格式:
第一行包含2個正整數\(N,M\),為圖的頂點數與邊數。
接下來\(M\)行,每行2個正整數\(x,y\),表示有一條頂點\(x\)連向頂點\(y\)的邊,請註意可能有自環與重邊。
輸出格式:
共\(N\)行,每行一個非負整數,第\(i\)行輸出從頂點1到頂點\(i\)有多少條不同的最短路,由於答案有可能會很大,你只需要輸出\(ans\) \(mod\) 100003後的結果即可。如果無法到達頂點\(i\)則輸出0 。
最短路計數,這個用spfa寫的。
思路和disj是一樣的社交網絡
Code:
#include <cstdio> #include <cstring> #include <queue> using namespace std; const int N=1000010; const int mod=100003; int head[N],to[N<<2],next[N<<2],cnt0; void add(int u,int v) { next[++cnt0]=head[u];to[cnt0]=v;head[u]=cnt0; next[++cnt0]=head[v];to[cnt0]=u;head[v]=cnt0; } int n,m,dis[N],used[N],cnt[N]; queue <int > q; void spfa() { memset(dis,0x3f,sizeof(dis)); dis[1]=0;cnt[1]=1; q.push(1); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i;i=next[i]) { int v=to[i]; if(dis[v]>dis[u]+1) { dis[v]=dis[u]+1; cnt[v]=cnt[u]; if(!used[v]) { used[v]=1; q.push(v); } } else if(dis[v]==dis[u]+1) cnt[v]=(cnt[v]+cnt[u])%mod; } } } int main() { scanf("%d%d",&n,&m); int u,v; for(int i=1;i<=m;i++) { scanf("%d%d",&u,&v); add(u,v); } spfa(); for(int i=1;i<=n;i++) printf("%d\n",cnt[i]); return 0; }
2018.7.1
洛谷 P1144 最短路計數 解題報告