大佬救命4、5TLE,关注,用的bfs

P1144 最短路计数

我自己优化了一下先排序,减少深搜时对边不必要的遍历,4、5过了但额外测试点还是过不了,求大佬帮忙 ``` #include <iostream> #include <queue> #include <algorithm> #include <stdio.h> using namespace std; struct edge { int a; int b; }; edge e[4000006]; int N; int M; int num[1000006] = { 0 }; int dist[1000006] = { 0 }; int Search[1000006]; queue<int>q; void bfs() { q.push(1); while (!q.empty()) { int e1 = q.front(); q.pop(); for (int i = Search[e1]; e[i].a == e1; i++) { int e2 = e[i].b; if (dist[e2] == 0 && e2 != 1) { dist[e2] = dist[e1] + 1; q.push(e2); num[e2] = (num[e2] + num[e1]) % 100003; } else if (dist[e2] == dist[e1] + 1) { num[e2] = (num[e2] + num[e1]) % 100003; } } } } bool judge(edge m, edge n) { return m.a < n.a; } int main() { cin >> N >> M; for (int i = 0; i < M; i++) { int x, y; cin >> x >> y; e[i].a = x; e[i].b = y; e[i + M].a = y; e[i + M].b = x; } sort(e, e + 2 * M, judge); //排序 int k = 0; for (int i = 0; i < 2 * M; i++) { if (k != e[i].a) //记录某一边的起始点在数列中出现的位置 { k = e[i].a; Search[k] = i; } } num[1] = 1; dist[1] = 0; bfs(); for (int i = 1; i <= N; i++) { cout << num[i] << endl; } return 0; } ```
by AIBEYOND @ 2024-03-13 19:48:11


看到的第一眼,以为是深搜,第二眼,发现是 优化 $\text{dijstra}$ ,再看一眼,好像是 $\text{Bellman Ford}$ ,最后一眼,好像都不是。 @[AIBEYOND](/user/1042314) 只能说很有实力,真的相当有实力,我是看不出是什么常规算法了,你可能硬生生自造了一个算法。 然而正解当然不是这样的,规定**最短距离为当前点到起点的最短距离**,既然是广搜,那么从 1 点开始,当**第一次到达某个点的时候,那么这个点的最短距离已确定**,接下来只需要计数了,然而**已经确定最短距离的点就无需再加入队列了**,因为确定者已经更新过其相连点的最短距离,无需二次加入队列。 具体地讲,进了队列的,处理后,标记一下,只有未标记的才进队列,直到队列中再无他点,你将得到正确答案。 你最好模拟一下,自己造个数据,这将让你有更深的理解。
by DHWJHY @ 2024-03-22 20:42:49


|