前置芝士:bfs,最短路。
思路
因為這張圖邊權相等,所以 bfs 每一次最先遍歷到的點肯定是最短路,所以我們不妨記錄一個 \(dis_i\) 表示到 \(i\) 的最短路徑,對於當前節點 \(u\),可以到達所有的 \(v\),我們討論一下:
- 當 \(v\) 未被訪問過,那麼將 \(v\) 設為已訪問,這個點的答案更新為 \(u\),並將它推入搜尋佇列。
- 當 \(v\) 已經被訪問過,仍然加上 \(u\) 的答案,但是不推入搜尋佇列,因為此時 \(v\) 已經在佇列中了。
記得勤取模。
時間複雜度:\(O(n+m)\)。
難點/坑點:無。
點選檢視程式碼
#include<bits/stdc++.h>
#define int i128
#define ll long long
#define i128 __int128
#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
using namespace std;
int read() {
int x=0,f=1; char c=getchar();
for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1);
for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }
const int mod = 100003;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }
#define maxn 1000050
int n,m;
vector<int>G[maxn];
bool vis[maxn];
int cnt[maxn],dis[maxn];
void work() {
in2(n,m);
cnt[1]=1;
For(i,1,m) {
int u,v;
in2(u,v);
pb(G[u],v);
pb(G[v],u);
}
queue<pair<int,int> >q;
q.push({1,0}); vis[1]=1;
while(!q.empty()) {
auto [u,d]=q.front(); q.pop();
for(auto v:G[u]) {
if(!vis[v]) {
vis[v]=1;
q.push({v,d+1});
dis[v]=d+1;
cnt[v]=cnt[u];
}
else if(d+1==dis[v]) (cnt[v]+=cnt[u])%=mod;
}
}
For(i,1,n) cout<<(ll)(cnt[i]%mod)<<'\n';
}
signed main() {
// ios::sync_with_stdio(false);
// cin.tie(0); cout.tie(0);
int _=1;
// int _=read();
For(i,1,_) {
work();
}
return 0;
}