洛谷P1144 最短路计数
-
- 205通过
- 739提交
- 题目提供者该用户不存在
- 标签图论
- 难度普及+/提高
提交该题 讨论 题解 记录
最新讨论
- 数据有毒
- 求神犇
- 无向图无向图无向图
- help
题目描述
给出一个N个顶点M条边的无向无权图,顶点编号为1~N。问从顶点1开始,到其他每个点的最短路有几条。
输入输出格式
输入格式:
输入第一行包含2个正整数N,M,为图的顶点数与边数。
接下来M行,每行两个正整数x, y,表示有一条顶点x连向顶点y的边,请注意可能有自环与重边。
输出格式:
输出包括N行,每行一个非负整数,第i行输出从顶点1到顶点i有多少条不同的最短路,由于答案有可能会很大,你只需要输出mod 100003后的结果即可。如果无法到达顶点i则输出0。
输入输出样例
输入样例#1:
5 7 1 2 1 3 2 4 3 4 2 3 4 5 4 5
输出样例#1:
1 1 1 2 4
说明
1到5的最短路有4条,分别为2条1-2-4-5和2条1-3-4-5(由于4-5的边有2条)。
对于20%的数据,N ≤ 100;
对于60%的数据,N ≤ 1000;
对于100%的数据,N ≤ 100000,M ≤ 200000。
分析:这道题有一个陷阱:告诉你一条边是u连向v,很容易认为是有向边,其实是无向边......既然是无向边,边权为1,那么就bfs一下.如果求到达点u的最短路的个数呢?设现在求到的最短路为v,如果从1到i到u的距离正好为v,那么点u的个数则应该加上点i的个数,同时要注意取模.
#include <cstdio> #include <queue> #include <iostream> #include <algorithm> #include <cstring> using namespace std; const int maxn = 1000010,mod = 100003; int head[maxn], to[maxn * 2], nextt[maxn * 2],tot,vis[maxn],d[maxn]; int n, m, cnt[maxn]; void add(int a, int b) { tot++; to[tot] = b; nextt[tot] = head[a]; head[a] = tot; } void bfs() { queue <int> q; q.push(1); d[1] = 0; cnt[1] = 1; vis[1] = 1; while (!q.empty()) { int u = q.front(); q.pop(); for (int i = head[u];i;i = nextt[i]) { int v = to[i]; if (!vis[v]) { vis[v] = 1; q.push(v); d[v] = d[u] + 1; cnt[v] = cnt[u]; } else if (d[v] == d[u] + 1) cnt[v] = (cnt[u] + cnt[v]) % mod; } } } int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= m; i++) { int u, v; scanf("%d%d", &u, &v); add(u, v); add(v, u); } bfs(); for (int i = 1; i <= n; i++) printf("%d\n", cnt[i]); return 0; }