main
黄海 2 years ago
parent 6099843cb7
commit 56e04c9ce6

@ -20,7 +20,7 @@ int id[N]; // 节点在哪个连通块中
vector<int> block[N]; // 连通块包含哪些节点 vector<int> block[N]; // 连通块包含哪些节点
int bcnt; // 连通块序号计数器 int bcnt; // 连通块序号计数器
int dist[N]; // 最短距离(结果数组) int dis[N]; // 最短距离(结果数组)
int in[N]; // 每个DAG(节点即连通块)的入度 int in[N]; // 每个DAG(节点即连通块)的入度
bool st[N]; // dijkstra用的是不是在队列中的数组 bool st[N]; // dijkstra用的是不是在队列中的数组
queue<int> q; // 拓扑序用的队列 queue<int> q; // 拓扑序用的队列
@ -31,8 +31,8 @@ void dfs(int u, int bid) {
block[bid].push_back(u); // ② 记录bid团包含u节点 block[bid].push_back(u); // ② 记录bid团包含u节点
// 枚举u节点的每一条出边将对端的城镇也加入到bid这个团中 // 枚举u节点的每一条出边将对端的城镇也加入到bid这个团中
for (int i = h[u]; ~i; i = ne[i]) { for (int i = h[u]; ~i; i = ne[i]) {
int v = e[i]; int j = e[i];
if (!id[v]) dfs(v, bid); // Flood Fill if (!id[j]) dfs(j, bid); // Flood Fill
} }
} }
@ -41,12 +41,12 @@ void dijkstra(int bid) {
priority_queue<PII, vector<PII>, greater<PII>> pq; priority_queue<PII, vector<PII>, greater<PII>> pq;
/* /*
distinf, disinf,
dijkstra dijkstra
din[] din[]
*/ */
for (auto u : block[bid]) pq.push({dist[u], u}); for (auto u : block[bid]) pq.push({dis[u], u});
while (pq.size()) { while (pq.size()) {
int u = pq.top().second; int u = pq.top().second;
@ -57,10 +57,10 @@ void dijkstra(int bid) {
int v = e[i]; int v = e[i];
if (st[v]) continue; if (st[v]) continue;
if (dist[v] > dist[u] + w[i]) { if (dis[v] > dis[u] + w[i]) {
dist[v] = dist[u] + w[i]; dis[v] = dis[u] + w[i];
// 如果是同团中的道路,需要再次进入Dijkstra的小顶堆以便计算完整个团中的路径最小值 // 如果是同团中的道路,需要再次进入Dijkstra的小顶堆以便计算完整个团中的路径最小值
if (id[u] == id[v]) pq.push({dist[v], v}); if (id[u] == id[v]) pq.push({dis[v], v});
} }
/*如果u和v不在同一个团中,说明遍历到的是航线 /*如果u和v不在同一个团中,说明遍历到的是航线
@ -92,12 +92,12 @@ int main() {
memset(h, -1, sizeof h); // 初始化 memset(h, -1, sizeof h); // 初始化
scanf("%d %d %d %d", &T, &R, &P, &S); // 城镇数量,道路数量,航线数量,出发点 scanf("%d %d %d %d", &T, &R, &P, &S); // 城镇数量,道路数量,航线数量,出发点
memset(dist, 0x3f, sizeof dist); // 初始化最短距离 memset(dis, 0x3f, sizeof dis); // 初始化最短距离
dist[S] = 0; // 出发点距离自己的长度是0,其它的最短距离目前是INF dis[S] = 0; // 出发点距离自己的长度是0,其它的最短距离目前是INF
int a, b, c; // 起点,终点,权值 int a, b, c; // 起点,终点,权值
while (R--) { // 读入道路 while (R--) { // 读入道路,团内无向图
scanf("%d %d %d", &a, &b, &c); scanf("%d %d %d", &a, &b, &c);
add(a, b, c), add(b, a, c); // 连通块内是无向图 add(a, b, c), add(b, a, c); // 连通块内是无向图
} }
@ -124,18 +124,18 @@ int main() {
while (P--) { while (P--) {
scanf("%d %d %d", &a, &b, &c); scanf("%d %d %d", &a, &b, &c);
add(a, b, c); // 单向边 add(a, b, c); // 单向边
in[id[b]]++; // b节点所在团入度+1 in[id[b]]++; // b节点所在团的番号,也就是某个团的入度+1
} }
// 拓扑 // 拓扑
topsort(); topsort();
// 从S到达城镇i的最小花费 // 从S到达城镇i的最小花费
for (int i = 1; i <= T; i++) { for (int i = 1; i <= T; i++) {
if (dist[i] > INF / 2) if (dis[i] > INF / 2)
puts("NO PATH"); puts("NO PATH");
else else
cout << dist[i] << endl; cout << dis[i] << endl;
} }
return 0; return 0;
} }

@ -97,7 +97,7 @@ int id[N]; // 节点在哪个连通块中
vector<int> block[N]; // 连通块包含哪些节点 vector<int> block[N]; // 连通块包含哪些节点
int bcnt; // 连通块序号计数器 int bcnt; // 连通块序号计数器
int dis[N]; // 最短距离(结果数组) int dis[N]; // 最短距离(结果数组)
int in[N]; // 每个DAG(节点即连通块)的入度 int in[N]; // 每个DAG(节点即连通块)的入度
bool st[N]; // dijkstra用的是不是在队列中的数组 bool st[N]; // dijkstra用的是不是在队列中的数组
queue<int> q; // 拓扑序用的队列 queue<int> q; // 拓扑序用的队列
@ -108,8 +108,8 @@ void dfs(int u, int bid) {
block[bid].push_back(u); // ② 记录bid团包含u节点 block[bid].push_back(u); // ② 记录bid团包含u节点
// 枚举u节点的每一条出边将对端的城镇也加入到bid这个团中 // 枚举u节点的每一条出边将对端的城镇也加入到bid这个团中
for (int i = h[u]; ~i; i = ne[i]) { for (int i = h[u]; ~i; i = ne[i]) {
int v = e[i]; int j = e[i];
if (!id[v]) dfs(v, bid); // Flood Fill if (!id[j]) dfs(j, bid); // Flood Fill
} }
} }
@ -170,11 +170,11 @@ int main() {
scanf("%d %d %d %d", &T, &R, &P, &S); // 城镇数量,道路数量,航线数量,出发点 scanf("%d %d %d %d", &T, &R, &P, &S); // 城镇数量,道路数量,航线数量,出发点
memset(dis, 0x3f, sizeof dis); // 初始化最短距离 memset(dis, 0x3f, sizeof dis); // 初始化最短距离
dis[S] = 0; // 出发点距离自己的长度是0,其它的最短距离目前是INF dis[S] = 0; // 出发点距离自己的长度是0,其它的最短距离目前是INF
int a, b, c; // 起点,终点,权值 int a, b, c; // 起点,终点,权值
while (R--) { // 读入道路 while (R--) { // 读入道路,团内无向图
scanf("%d %d %d", &a, &b, &c); scanf("%d %d %d", &a, &b, &c);
add(a, b, c), add(b, a, c); // 连通块内是无向图 add(a, b, c), add(b, a, c); // 连通块内是无向图
} }
@ -201,10 +201,10 @@ int main() {
while (P--) { while (P--) {
scanf("%d %d %d", &a, &b, &c); scanf("%d %d %d", &a, &b, &c);
add(a, b, c); // 单向边 add(a, b, c); // 单向边
in[id[b]]++; // b节点所在团入度+1 in[id[b]]++; // b节点所在团的番号,也就是某个团的入度+1
} }
// 拓扑 // 拓扑
topsort(); topsort();
// 从S到达城镇i的最小花费 // 从S到达城镇i的最小花费

Loading…
Cancel
Save