9.2 图论专项四模拟赛小记
A.最短路,原题洛谷指路:P1144 最短路计数
看评测一开始 0pts,死于无向边看成单向边。后来在洛谷提交的时候调了好久好久,死于数组开小。
其他没什么,就是一个 dijkstra 的板子。转移路径的时候,若这条路比当前的路长度小,那这条路的答案就更新为转移过来新路的答案;若这条路和当前路长度一样,那将答案加上新路。
#include<bits/stdc++.h>
using namespace std;
const int N = 2e6 + 10;
const int mod = 1e5 + 3;
int n, m;
int vis[N];
priority_queue< pair<int, int> > q;
int idx, e[N], w[N], nxt[N], head[N];
struct node{int d, tot;}ans[N];
void add(int x, int y, int z)
{
e[++ idx] = y;
w[idx] = z;
nxt[idx] = head[x];
head[x] = idx;
}
void dij()
{
ans[1].d = 0;
ans[1].tot = 1;
q.push(make_pair(0, 1));
while(q.size())
{
int x = q.top().second;
q.pop();
if(vis[x]) continue;
vis[x] = 1;
for(int i = head[x]; i; i = nxt[i])
{
if(ans[e[i]].d == ans[x].d + 1) ans[e[i]].tot = (ans[e[i]].tot + ans[x].tot) % mod;
else if(ans[e[i]].d > ans[x].d + 1)
{
ans[e[i]].d = ans[x].d + 1;
ans[e[i]].tot = ans[x].tot % mod;
q.push(make_pair(-ans[e[i]].d, e[i]));
}
}
}
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++ ) ans[i].d = 1e9;
while(m -- )
{
int x, y;
scanf("%d%d", &x, &y);
add(y, x, 1);
add(x, y, 1);
}
dij();
for(int i = 1; i <= n; i ++ ) printf("%d\n", ans[i].tot % mod);
return 0;
}