代码求调
  • 板块灌水区
  • 楼主MOwansui
  • 当前回复12
  • 已保存回复12
  • 发布时间2023/4/24 20:30
  • 上次更新2023/10/23 17:37:50
查看原帖
代码求调
919136
MOwansui楼主2023/4/24 20:30

给我c++代码,用Bellman-Ford:

你发现在特定地点有时光机存在,能回到过去,只可惜钻进时光机后并不能保证还出现在同一地点。你盘算着,有没有可能通过各地点间若干次走动和穿越,最终回到同一地点完成时光倒退?
共n个地点,编号1到n。共p种穿越方式,每一种方式包含起点,终点,和倒退几秒。另外共m条正常双向马路,连接两个地点,走完需要花时间。
输入输出格式
输入格式
输入文件timemachine.in 输入第一行为正整数n,p,m。接着是p行,每行包含三个整数代表一种穿越方式:起点,终点,和倒退几秒。接着是m行,每行包含三个整数代表一条路的信息:连接哪两个点的编号,走完需要几秒。n<=500,p<=200,m<=2500.其他数据不超过10000.
输出格式
输出文件timemachine.out 输出Yes或者No
输入输出样例
输入样例#1:
3 1 3
3 1 3
1 2 2
1 3 4
2 3 1
输出样例#1:
No
输入样例#2:
3 1 2
3 1 8
1 2 3
2 3 4
输出样例#2:
Yes

目前:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 5101, M = 25110;

int n, m, p;
struct Edge
{
    int a, b, c; // 起点,终点,时间差(倒退几秒)
}e[11111]; // 注意边数为 m+n+1
int h[N], idx;
int dist[N];
bool st[N];

void add(int a, int b, int c)
{
    e[idx] = {a, b, -c}; // 将时间差取相反数,这样可以转化为最短路问题
    idx ++ ;
}

bool spfa()
{
    memset(dist, 0x3f, sizeof dist);
    dist[1] = 0;
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < idx; j ++ )
        {
            int a = e[j].a, b = e[j].b, c = e[j].c;
            if (dist[b] > dist[a] + c) // 松弛操作
            {
                dist[b] = dist[a] + c;
                if (i >= n && b == 1) return true; // 存在负环返回 true
            }
        }
    return false;
}

int main()
{
  freopen("timemachine.in","r",stdin);
  freopen("timemachine.out","w",stdout);
    cin >> n >> p >> m;

    for (int i = 0; i < p; i ++ )
    {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        add(b, a, c); // 注意这里是倒退 c 秒,所以起点和终点要反过来
    }

    for (int i = 0; i < p; i ++ )
    {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        add(a, b, c);
        add(b, a, c);
    }

    add(0, 1, 0); // 添加一个虚拟源点 0,并连一条边到点 1

    if (spfa()) puts("Yes");
    else puts("No");

    return 0;
}
2023/4/24 20:30
加载中...