题意:题意就是给你一些钱和一些货币兑换点,问你能否经过一系列兑换使自己钱的价值增加(好神奇的操作)
题解:这题好久之前好像做过,但是当时太菜了应该看了题解草草过了,这样来看就是要看所给的图中是否有一个正环。
用spfa解决就好了,还可以用floyd或者贝尔曼福德。
刺激。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
#define inf 99999999
const int maxn = 105;
double dis[maxn],rate[maxn][maxn],cost[maxn][maxn];
bool vis[maxn];
int n,m,f,cnt[maxn];
double money;
void init()
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if(i == j)
rate[i][j] = 0,cost[i][j] = 0;
else rate[i][j] = inf,cost[i][j] = inf;
}
}
memset(cnt,0,sizeof cnt);
}
int spfa()
{
for (int i = 0; i < n; i++)
dis[i] = 0,vis[i] = 0;
queue<int> q;
q.push(f);
dis[f] = money,vis[f] = 1;
while (!q.empty())
{
int now = q.front();
q.pop();
vis[now] = 0;
for (int i = 1; i<= n; i++)
{
if(rate[now][i] != inf&&dis[i] < (dis[now] - cost[now][i]) * rate[now][i])
{
dis[i] = (dis[now] - cost[now][i]) * rate[now][i];
if(!vis[i])
{
vis[i] = 1;
q.push(i);
}
cnt[i]++;
if(dis[f] > money||cnt[i] >= 10000)
{
return 1;
}
}
}
}
return 0;
}
int main()
{
while (~scanf("%d %d %d %lf",&n,&m,&f,&money))
{
init();
int a,b;
double r1,r2,c1,c2;
for (int i = 0; i < m; i++)
{
scanf("%d %d %lf %lf %lf %lf",&a,&b,&r1,&c1,&r2,&c2);
rate[a][b] = r1;
cost[a][b] = c1;
rate[b][a] = r2;
cost[b][a] = c2;
}
if(spfa())
{
printf("YES\n");
}
else printf("NO\n");
}
}