题目大意:你在某一点有一些钱,给定你两点之间钱得兑换规则,问你有没有办法使你手里的钱增多。就是想看看转一圈我的钱能不能增多,出现这一点得条件就是有兑换钱得正权回路,所以选择用bellman_ford得算法
准备工作,bellman_ford得更新是根据已知边得数据来的,所以需要存住边的数据,还要有dis数组作为更新判断,dis也就相当于中心节点得钱兑换到i节点(中间可能会经过别的)变成了多少钱
#include <iostream> #include <string.h> #include <cstdio> #define inf 0x3f3f3f3f using namespace std; const int maxn = 110; struct node{ int from,to; double r,c; }edge[maxn * 2]; double d[maxn];
根据题意,存储边的数据
for(int i = 1;i <= m * 2;i++) { scanf("%d %d %lf %lf %lf %lf",&a,&b,&r1,&c1,&r2,&c2); edge[i].from = a;edge[i].to = b; edge[i].r = r1;edge[i].c = c1; i++; edge[i].from = b;edge[i].to = a; edge[i].r = r2;edge[i].c = c2; }
进行bellman_ford算法,进行钱财得初始化,初始化d时要根据其含义和松弛得判断条件来进行初始化,然后松弛n次,再进行判断,如果还能松弛,那就代表有正权回路返回True~~
bool Bellman_ford(int n,int s,double v,int len) { for(int i = 1;i <= n;i++)d[i] = 0.0; d[s] = v; for(int i = 1;i <= n;i++) { bool flag = true; for(int j = 1;j <= len ;j++) { int from = edge[j].from; int to = edge[j].to; double r = edge[j].r; double c = edge[j].c; if(d[to] < (d[from] - c) * r) { d[to] = (d[from] - c) * r; flag = false; } } if(flag)return false; } for(int i = 1;i <= len;i++) { if(d[edge[i].to] < (d[edge[i].from] - edge[i].c) * edge[i].r) { return true; } } return false; }