题目描述
给出一个NNN个顶点MMM条边的无向无权图,顶点编号为1−N1-N1−N。问从顶点111开始,到其他每个点的最短路有几条。
输入格式
第一行包含2个正整数N,MN,MN,M,为图的顶点数与边数。
接下来M行,每行2个正整数x,y,表示有一条顶点x连向顶点y的边,请注意可能有自环与重边。
输出格式
共NNN行,每行一个非负整数,第iii行输出从顶点111到顶点iii有多少条不同的最短路,由于答案有可能会很大,你只需要输出ans mod 100003 ans \bmod 100003ansmod100003后的结果即可。如果无法到达顶点iii则输出000。
输入输出样例
输入 #1 复制
5 7
1 2
1 3
2 4
3 4
2 3
4 5
4 5
输出 #1 复制
1
1
1
2
4
说明/提示
111到555的最短路有444条,分别为222条1−2−4−51-2-4-51−2−4−5和222条1−3−4−51-3-4-51−3−4−5(由于4−54-54−5的边有222条)。
对于20%20\%20%的数据,N≤100N ≤ 100N≤100;
对于60%60\%60%的数据,N≤1000N ≤ 1000N≤1000;
对于100%100\%100%的数据,N<=1000000,M<=2000000N<=1000000,M<=2000000N<=1000000,M<=2000000。
AC 的代码
#include<bits/stdc++.h>
using namespace std;
const int MOD = 100003;
const int N = 1000000*2 +3;
const int M = 2000000*2 + 5;
int n,m;
struct Edge{
int u,v,next;
}e[M];
int head[N], cnt;
int dist[N];
bool vis[N];
int dist_cnt[N];
struct State {
int w;
int from;
bool operator < (const State &x) const {
return w> x.w;
}
};
void reset() {
for(int i=0;i<=n;++i) dist[i] = INT_MAX;
}
void add(int x,int y) {
Edge &edg = e[++cnt];
edg.u = x,edg.v = y;
edg.next = head[x];
head[x] = cnt;
}
queue<int> q;
void dijkstra() {
reset();
dist[1] = 0;
dist_cnt[1] = 1;
q.push(1);
while(q.size()) {
int t = q.front();q.pop();
int h = head[t];
while(h) {
Edge& edg = e[h];
//cout <<" t: "<< t <<" u: "<< edg.u << " edg.v : "<<edg.v <<"dist[v]: "<<dist[edg.v] << endl;
if(dist[edg.v] > dist[t] + 1) {
dist[edg.v] = dist[t]+1;
dist_cnt[edg.v] = dist_cnt[t];
q.push(edg.v);
}else if(dist[edg.v] == dist[t] + 1) {
dist_cnt[edg.v] = (dist_cnt[edg.v] + dist_cnt[t])%MOD;
}
h = edg.next;
}
}
}
int main(void) {
cin>>n>>m;
for(int i=0;i<m;++i) {
int x,y;
cin>>x>>y;
if(x==y) continue;
add(x,y);
add(y,x);
}
dijkstra();
for(int i=1;i<=n;++i) cout << dist_cnt[i] <<endl;
return 0;
}