hdu1217(spfa,存在环,但需要将环的元素历遍一次.....求乘积的最大)

题意:有n个国家货币,给出m种两个国家之间的货币兑换率,求是否可以盈利.......

思路:其实就是看国家货币兑换间是否存在一个环,使得从v点出发时,dis[v]=1,经过环回到v点时,dis[v]>1.......当然,路径是单向的。这个题目的松弛是:dis[i]<dis[v]*map[v][i],只单单spfa来说,要判断存在一个正环,那么就是某个点被历遍>=n+1次,从而判断这个环不存在“最大路”.....但是,就这题目而已,我们不需要判断最大路是否存在,我们只需要判断,是否可以盈利。可以盈利的话,那么从某个点p出发,经过一个环,回到点p,通过松弛,dis[p]>1,说明可以盈利,否则就是不能。那么可以使用数组进行标记,每次一个点可以松弛(就是满足dis[i]<dis[v]*map[v][i]),那么先更新这个点的最大值,然后判断这个点是否在队列里面,在的话,就不需要压入队列,否则压入队列......一个点出队列的时候,它相应的标记数要清零.......

#include<iostream>

#include<cstdio>

#include<cstring>

#include<vector>

#include<queue>

using namespace std;

struct node

{

    int e;

    double d;

};

char t[50][100],s[1000][100],s1[1000][100],vist[1000];

int n,m,flg;

double dis[100],x[1000];

vector<node>vet[1000];



void spfa(int v)

{

    for(int i=0;i<=n;i++)

    dis[i]=0;

    dis[v]=1.0;

    queue<int>q;

    q.push(v);

    vist[v]=1;

    while(!q.empty())

    {

        int u=q.front();

        q.pop();

        vist[u]=0;

        for(int i=0;i<vet[u].size();i++)

        {

            node p=vet[u][i];

            //printf("%d %d %.3lf\n",u,p.e,p.d);



            if(dis[p.e]<dis[u]*p.d)

            {

                dis[p.e]=dis[u]*p.d;

                //vist[p.e]=1;

                if(vist[p.e]==0)

                q.push(p.e);

                vist[p.e]=1;

                if(dis[v]>1.0)

                {

                    flg=1;

                    return;

                }

            }

        }

    }

}

int main()

{

    int text=0;

    while(scanf("%d",&n)>0&&n)

    {

        for(int i=0;i<n;i++)

        scanf("%s",t[i]);

        for(int i=0;i<=n;i++)

        vet[i].clear();



        scanf("%d",&m);

        for(int i=0;i<m;i++)

        {

            scanf("%s %lf %s",s[i],&x[i],s1[i]);

            int xx,yy;

            for(int j=0;j<n;j++)

            {

                if(strcmp(s[i],t[j])==0)

                {

                    xx=j;

                }

                if(strcmp(s1[i],t[j])==0)

                {

                    yy=j;

                }

            }

            node p;

            p.e=yy;

            p.d=x[i];

            vet[xx].push_back(p);

            //p.e=xx;

            //vet[yy].push_back(p);

        }

        int i;

        printf("Case %d: ",++text);

        for(i=0;i<n;i++)

        {

            flg=0;

            memset(vist,0,sizeof(vist));

            spfa(i);

            if(flg==1)

            {

                printf("Yes\n");

                break;

            }

        }

        if(i==n)

        printf("No\n");

    }

    return 0;

}

 

你可能感兴趣的:(SPFA)