【正经题解】虫洞
2024-03-18 13:39:09
发布于:浙江
12阅读
0回复
0点赞
定义了一个邻接表 来表示地点之间的连接关系,包括小路和虫洞。
使用 和 数组分别记录从 号地点到其他地点的最短时间和通过虫洞的最短时间。
对于虫洞,将其信息添加到邻接表 中,并进行松弛操作更新 。
对于小路,同样将其信息添加到邻接表 中,并进行松弛操作更新 。
最后检查是否存在通过小路和虫洞能够回到过去的情况,输出相应的结果。
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n, m, w;
int dis[510], dis2[510];
int e[60000][3], se;
void work() {
memset(e, 0, sizeof(e));
se = 0;
// 处理小路
for (int i = 1; i <= m; i++) {
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
e[++se][0] = x; e[se][1] = y; e[se][2] = z;
e[++se][0] = y; e[se][1] = x; e[se][2] = z;
}
// 处理虫洞
for (int i = 1; i <= w; i++) {
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
e[++se][0] = x; e[se][1] = y; e[se][2] = -z; // 注意虫洞时间的处理
}
memset(dis, 10, sizeof(dis));
memset(dis2, 10, sizeof(dis2));
dis[1] = 0;
dis2[1] = 0;
// 更新虫洞的最短时间
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= se; j++) {
int x = e[j][1], y = e[j][0], z = 0;
if (dis2[x] + z < dis2[y]) {
dis2[y] = dis2[x] + z;
}
}
}
// 更新小路的最短时间
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= se; j++) {
int x = e[j][0], y = e[j][1], z = e[j][2];
if (dis[x] + z < dis[y]) {
dis[y] = dis[x] + z;
}
}
}
// 检查是否存在通过小路和虫洞能够回到过去的情况
for (int j = 1; j <= se; j++) {
int x = e[j][0], y = e[j][1], z = e[j][2];
if (dis[x] + z < dis[y]) {
if (dis2[y] == 0) {
printf("YES\n");
return;
}
}
}
printf("NO\n");
return;
}
int main() {
while (scanf("%d%d%d", &n, &m, &w) != EOF) {
work();
}
return 0;
}
这里空空如也
有帮助,赞一个