diff --git a/TangDou/AcWing_TiGao/T3/MiniPathYingYong/342.cpp b/TangDou/AcWing_TiGao/T3/MiniPathYingYong/342.cpp index 917fec2..ad895fa 100644 --- a/TangDou/AcWing_TiGao/T3/MiniPathYingYong/342.cpp +++ b/TangDou/AcWing_TiGao/T3/MiniPathYingYong/342.cpp @@ -20,7 +20,7 @@ int id[N]; // 节点在哪个连通块中 vector block[N]; // 连通块包含哪些节点 int bcnt; // 连通块序号计数器 -int dist[N]; // 最短距离(结果数组) +int dis[N]; // 最短距离(结果数组) int in[N]; // 每个DAG(节点即连通块)的入度 bool st[N]; // dijkstra用的是不是在队列中的数组 queue q; // 拓扑序用的队列 @@ -31,8 +31,8 @@ void dfs(int u, int bid) { block[bid].push_back(u); // ② 记录bid团包含u节点 // 枚举u节点的每一条出边,将对端的城镇也加入到bid这个团中 for (int i = h[u]; ~i; i = ne[i]) { - int v = e[i]; - if (!id[v]) dfs(v, bid); // Flood Fill + int j = e[i]; + if (!id[j]) dfs(j, bid); // Flood Fill } } @@ -41,12 +41,12 @@ void dijkstra(int bid) { priority_queue, greater> pq; /* 因为不确定连通块内的哪个点可以作为起点,所以就一股脑全加进来就行了, - 反正很多点的dist都是inf(这些都是不能成为起点的),那么可以作为起点的就自然出现在堆顶了 + 反正很多点的dis都是inf(这些都是不能成为起点的),那么可以作为起点的就自然出现在堆顶了 因为上面的写法把拓扑排序和dijkstra算法拼在一起了,如果不把所有点都加入堆, 会导致后面其他块的din[]没有减去前驱边,从而某些块没有被拓扑排序遍历到。 */ - for (auto u : block[bid]) pq.push({dist[u], u}); + for (auto u : block[bid]) pq.push({dis[u], u}); while (pq.size()) { int u = pq.top().second; @@ -57,10 +57,10 @@ void dijkstra(int bid) { int v = e[i]; if (st[v]) continue; - if (dist[v] > dist[u] + w[i]) { - dist[v] = dist[u] + w[i]; + if (dis[v] > dis[u] + w[i]) { + dis[v] = dis[u] + w[i]; // 如果是同团中的道路,需要再次进入Dijkstra的小顶堆,以便计算完整个团中的路径最小值 - if (id[u] == id[v]) pq.push({dist[v], v}); + if (id[u] == id[v]) pq.push({dis[v], v}); } /*如果u和v不在同一个团中,说明遍历到的是航线 此时,需要与拓扑序算法结合,尝试剪掉此边,是不是可以形成入度为的团 @@ -92,12 +92,12 @@ int main() { memset(h, -1, sizeof h); // 初始化 scanf("%d %d %d %d", &T, &R, &P, &S); // 城镇数量,道路数量,航线数量,出发点 - memset(dist, 0x3f, sizeof dist); // 初始化最短距离 - dist[S] = 0; // 出发点距离自己的长度是0,其它的最短距离目前是INF + memset(dis, 0x3f, sizeof dis); // 初始化最短距离 + dis[S] = 0; // 出发点距离自己的长度是0,其它的最短距离目前是INF int a, b, c; // 起点,终点,权值 - while (R--) { // 读入道路 + while (R--) { // 读入道路,团内无向图 scanf("%d %d %d", &a, &b, &c); add(a, b, c), add(b, a, c); // 连通块内是无向图 } @@ -124,18 +124,18 @@ int main() { while (P--) { scanf("%d %d %d", &a, &b, &c); add(a, b, c); // 单向边 - in[id[b]]++; // b节点所在团入度+1 + in[id[b]]++; // b节点所在团的番号,也就是某个团的入度+1 } - // 拓扑序 + // 拓扑 topsort(); // 从S到达城镇i的最小花费 for (int i = 1; i <= T; i++) { - if (dist[i] > INF / 2) + if (dis[i] > INF / 2) puts("NO PATH"); else - cout << dist[i] << endl; + cout << dis[i] << endl; } return 0; } \ No newline at end of file diff --git a/TangDou/AcWing_TiGao/T3/MiniPathYingYong/342.md b/TangDou/AcWing_TiGao/T3/MiniPathYingYong/342.md index 8c52fcb..1e64079 100644 --- a/TangDou/AcWing_TiGao/T3/MiniPathYingYong/342.md +++ b/TangDou/AcWing_TiGao/T3/MiniPathYingYong/342.md @@ -97,7 +97,7 @@ int id[N]; // 节点在哪个连通块中 vector block[N]; // 连通块包含哪些节点 int bcnt; // 连通块序号计数器 -int dis[N]; // 最短距离(结果数组) +int dis[N]; // 最短距离(结果数组) int in[N]; // 每个DAG(节点即连通块)的入度 bool st[N]; // dijkstra用的是不是在队列中的数组 queue q; // 拓扑序用的队列 @@ -108,8 +108,8 @@ void dfs(int u, int bid) { block[bid].push_back(u); // ② 记录bid团包含u节点 // 枚举u节点的每一条出边,将对端的城镇也加入到bid这个团中 for (int i = h[u]; ~i; i = ne[i]) { - int v = e[i]; - if (!id[v]) dfs(v, bid); // Flood Fill + int j = e[i]; + if (!id[j]) dfs(j, bid); // Flood Fill } } @@ -170,11 +170,11 @@ int main() { scanf("%d %d %d %d", &T, &R, &P, &S); // 城镇数量,道路数量,航线数量,出发点 memset(dis, 0x3f, sizeof dis); // 初始化最短距离 - dis[S] = 0; // 出发点距离自己的长度是0,其它的最短距离目前是INF + dis[S] = 0; // 出发点距离自己的长度是0,其它的最短距离目前是INF int a, b, c; // 起点,终点,权值 - while (R--) { // 读入道路 + while (R--) { // 读入道路,团内无向图 scanf("%d %d %d", &a, &b, &c); add(a, b, c), add(b, a, c); // 连通块内是无向图 } @@ -201,10 +201,10 @@ int main() { while (P--) { scanf("%d %d %d", &a, &b, &c); add(a, b, c); // 单向边 - in[id[b]]++; // b节点所在团入度+1 + in[id[b]]++; // b节点所在团的番号,也就是某个团的入度+1 } - // 拓扑序 + // 拓扑 topsort(); // 从S到达城镇i的最小花费