poj1860 Currency Exchange 最短路变形 spfa 判环 思考

来源:互联网 发布:济南网络广告公司 编辑:程序博客网 时间:2024/05/16 08:57

                                       POJ 1860

题目大意:

有个城市有m种货币,n个货币兑换站。每两种货币兑换分别有相应的汇率和手续费。

例如,你现在有s个A货币,那么用A货币兑换B货币,你可得到(s-cab(A兑换B的手续费))*Rab(A兑换B的汇率)个B货币。

你现在有第S种货币V个,然后问你,是否能通过一系列的兑换,使得最后自己手中的第S种增加了。。。

大致思路:

此题要用最短路的思想进行求解,dis[i]代表当我兑换了第i种货币时,能兑换的数量。那么要使得原来的货币数量增加,那肯定是通过一系列的兑换之后,使得dis[start]>dis[start](开始的,即V)。

既然能回来,那说明一定会有环。既然有环,我们就要使用Bellman-Ford算法或者spfa。这两种都是可以进行存在环的的寻求最短路算法。我选用的是spfa算法,当存在dis[start]>V时就说明成功了。

此题和原来的最短路思想恰好相反,我们要把dis数组初始化为0。然后当兑换的货币数量大于原来的,就进行松弛。

代码:

#include<stdio.h>#include<iostream>#include<string.h>#include<vector>#include<queue>using namespace std;double dis[105];int vis[105];int m,n,s;double v;struct Node{    int to;    double rat,cos;    Node(int too,double ratt,double coss)    {        to=too;        rat=ratt;        cos=coss;    }};vector<Node>V[105];//用vector存图void init(){    for(int i=1; i<=105; i++)        V[i].clear();    int a,b;    double rab,cab,rba,cba;    for(int i=0; i<n; i++)    {        scanf("%d%d%lf%lf%lf%lf",&a,&b,&rab,&cab,&rba,&cba);        V[a].push_back(Node(b,rab,cab));        V[b].push_back(Node(a,rba,cba));    }    return;}int spfa()//我们要的是spfa的这种思想,这题并不是求最短路。。{    queue<int>Q;    while(!Q.empty())Q.pop();    for(int i=0; i<=105; i++)    {        dis[i]=0;//初始化成0.当兑换第i种货币时,若大于原来的,就进行松弛。        vis[i]=0;    }    dis[s]=v;    Q.push(s);    vis[s]=1;    while(!Q.empty())    {        int top=Q.front();        Q.pop();        vis[top]=0;        for(int i=0;i<V[top].size();i++)        {            if(dis[V[top][i].to]<(dis[top]-V[top][i].cos)*V[top][i].rat)            {                  dis[V[top][i].to]=(dis[top]-V[top][i].cos)*V[top][i].rat;//cout<<"++"<<dis[V[top][i].to]<<endl;                  if(!vis[V[top][i].to])                  {                      Q.push(V[top][i].to);                      vis[V[top][i].to]=1;                  }            }            if(dis[s]>v)//增值了,成功了                return 1;        }    }    return 0;}int main(){    scanf("%d%d%d%lf",&m,&n,&s,&v);    init();    if(spfa())        printf("YES\n");    else        printf("NO\n");}