题目地址:http://poj.org/problem?id=1860
题意就看看这位大佬翻译的吧,https://blog.csdn.net/yslcl12345/article/details/50574213
这个题就是对Bellman-ford的一个反向应用,这个题问你能不能找到一种方式,让他的钱捣鼓捣鼓就能变多,平时的话Bellman-ford算法能找到一个负权回路,这个题要求钱数增多,那也就是找一个正权回路就可以了,需要注意的是不能再把dis数组初始化为INF了,现在需要将数组初始化为无穷小也就是0,可能有人就问了,为什么不是负无穷而是0呢,因为如果初始化为负无穷的话,对于题目中给的负值就也能使其增大了,实际并没有增大。
AC代码:
#include <iostream>
#include <vector>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAX_N = 50001;
const int MIN = 0;
double dis[MAX_N];
int num = 0;
struct edge
{
int u, v;
double rate, money;
};
struct edge G[MAX_N];
void init(int n)
{
for (int i=1; i<=n; i++)
{
dis[i] = MIN;
}
}
bool Bellman_ford(int n)
{
for (int i=1; i<=n; i++)
{
bool flag = false;
for (int j=0; j<num; j++)
{
if (dis[G[j].v] < (dis[G[j].u] - G[j].money) * G[j].rate)
{
dis[G[j].v] = (dis[G[j].u] - G[j].money) * G[j].rate;
flag = true;
if (i == n)
{
return true;
}
}
}
if (!flag)
{
break;
}
}
return false;
}
int main()
{
int n, m, s;
double money;
scanf("%d %d %d %lf", &n, &m, &s, &money);
for (int i=1; i<=m; i++)
{
int a, b;
double c, d, e, f;
scanf("%d %d %lf %lf %lf %lf", &a, &b, &c, &d, &e, &f);
G[num].u = a;
G[num].v = b;
G[num].rate = c;
G[num++].money = d;
G[num].u = b;
G[num].v = a;
G[num].rate = e;
G[num++].money = f;
}
init(n);
dis[s] = money;
if (Bellman_ford(n))
{
printf("YES\n");
}
else
{
printf("NO\n");
}
return 0;
}