题意:

现在有n种类型(1-n)的货币, m个城市,每个城市你可以 将a货币换成b货币, 汇率为r, 每换一次要先收取佣金c

现在先输入n, m,    s(代表你一开始拥有的货币类型), v(你所拥有的货币量)

输入m行

aa, bb, r1, c1, r2, c2  货币aa换成货币bb的汇率为 r1, 佣金为c1, 货币bb换成货币aa的汇率为 r2, 佣金为c2

请问存不存在兑换若干次后, 存在钱的价值增加(即正权回路)

题解:

一般负权回路,我们用bellman-ford算法,判断正权回路也可,只要把松弛操作和初始化改一下即可

求最小路径 变为 求最大路径

AC_code:

/*
Algorithm:bellman-ford
Author: anthony1314
Creat Time:
Time Complexity:
*/

#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cstring>
#include<cstdio>
//#include<bits/stdc++.h>
#define ll long long
#define maxn 1005
#define mod 1e9 + 7
#define line printf("--------------");
using namespace std;
int n, m, s;
int tot;
double v, dis[105];
struct node {
	int a, b;
	double r, c;
} edge[205];//边的结构体
bool bellmanford() {
	memset(dis, 0, sizeof(dis));//先初始化为最小
	dis[s] = v;
	bool flag;
	for(int i = 1; i < n; i++) {
		flag = false;
		for(int j = 0; j < tot; j++) {
			if(dis[edge[j].b] < (dis[edge[j].a] - edge[j].c) * edge[j].r) { //松弛操作
				flag = true;
				dis[edge[j].b] = (dis[edge[j].a] - edge[j].c) * edge[j].r;
			}
		}
		if(!flag) {
			return false;
		}
	}
	for(int i = 0; i < tot; i++) {
		if(dis[edge[i].b] < (dis[edge[i].a] - edge[i].c) * edge[i].r) {
			return true;
		}
	}
	return false;
}
int main() {
	while(cin>>n>>m>>s>>v) {
		tot = 0;
		int aa, bb;
		double r1, c1, r2, c2;
		for(int i = 0; i < m; i++) {
			scanf("%d %d %lf %lf %lf %lf", &aa, &bb, &r1, &c1, &r2, &c2);
			edge[tot].a = aa;
			edge[tot].b = bb;
			edge[tot].r = r1;
			edge[tot++].c = c1;
			edge[tot].a = bb;
			edge[tot].b = aa;
			edge[tot].r = r2;
			edge[tot++].c = c2;
		}
		if(bellmanford()) {
			cout<<"YES"<<endl;
		} else {
			cout<<"NO"<<endl;
		}
	}
	return 0;
}