给我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;
}