poj1860(spfa)

来源:互联网 发布:商务数据分析与应用 编辑:程序博客网 时间:2024/06/11 08:26

题目

题意:题意就是给你一些钱和一些货币兑换点,问你能否经过一系列兑换使自己钱的价值增加(好神奇的操作)

题解:这题好久之前好像做过,但是当时太菜了应该看了题解草草过了,这样来看就是要看所给的图中是否有一个正环。
用spfa解决就好了,还可以用floyd或者贝尔曼福德。
刺激。

#include<cstdio>#include<algorithm>#include<cstring>#include<queue>using namespace std;#define inf 99999999const 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");    }}