P1144 最短路计数
题目描述
给出一个N个顶点M条边的无向无权图,顶点编号为1−N。问从顶点1开始,到其他每个点的最短路有几条。
输入格式
第一行包含222个正整数N,M,为图的顶点数与边数。
接下来M行,每行2个正整数x,y,表示有一条顶点x连向顶点y的边,请注意可能有自环与重边。
输出格式
共N行,每行一个非负整数,第iii行输出从顶点111到顶点iii有多少条不同的最短路,由于答案有可能会很大,你只需要输出ans mod 100003后的结果即可。如果无法到达顶点i则输出0。
输入输出样例
输入
5 7
1 2
1 3
2 4
3 4
2 3
4 5
4 5
输出
1
1
1
2
4
#include <bits/stdc++.h>
using namespace std;
const int mod = 100003;
const int maxn = 1e6+5;
const int inf = 0x3f3f3f3f;
int dis[maxn],num[maxn];
bool vis[maxn];
int n,m;
struct node
{
int v,w;
node(int vv , int ww):v(vv),w(ww){}
};
vector <node> e[maxn];
void add_edge(int u , int v , int w)
{
e[u].push_back(node(v,w));
}
void Spfa(int st,int ed)
{
fill(vis,vis+maxn,false);
fill(dis,dis+maxn,inf);
queue <int> q;
q.push(st);
vis[st] = true;
dis[st] = 0;
num[st] = 1;
while(!q.empty())
{
int u = q.front();
q.pop();
for(int i = 0 ; i < e[u].size(); i++)
{
int v = e[u][i].v;
int w = e[u][i].w;
if(dis[v] > dis[u] + w)
{
num[v] = num[u] % mod;
dis[v] = dis[u] + w;
if(!vis[v])
{
q.push(v);
vis[v] = true;
}
}
else if(dis[v] == dis[u] + w) //路径长度相等就相加
num[v] = (num[v] % mod + num[u] % mod)%mod;//(a+b)%c = (a%c + b%c)%c
}
vis[u] = false;
}
}
int main()
{
cin >> n >> m;
for(int i = 0 ; i < m ; i++)
{
int u,v;
cin >> u >> v;
add_edge(u,v,1);
add_edge(v,u,1);
}
Spfa(1,n);
for(int i = 1 ; i <= n ; i++)
cout << num[i] << endl;
return 0;
}