Poj1860

题目大意:给顶每条边的汇率和所花费的手续费,让你求是否会比原来的钱多。

算法思想:spfa的变形,只需要判断是否存在正环即可,但要注意精度问题,又在这精度上wa了好几次,还是太粗心了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int n,s,sym;
double v;
int a,b,e;
double ex,ch,ex2,ch2;
bool visited[300];
int head[300],next[300];
double dist[300];
int num[300];
typedef struct Edge
{
    int u;
    int v;
    double cc;
    double ee;
};
Edge edges[300];
void addNode(int u,int v,double cc,double ee)
{
    edges[e].u=u;
    edges[e].v=v;
    edges[e].cc=cc;
    edges[e].ee=ee;
    next[e]=head[u];
    head[u]=e++;
}
bool relax(int u,int v,double cc,double ee)
{
    if(dist[v]<(dist[u]-cc)*ee)
    {
        dist[v]=(dist[u]-cc)*ee;
        return true;
    }
    return false;

}
bool spfa(int src,double value)
{
    memset(num,0,sizeof(num));
    memset(visited,false,sizeof(visited));
    queue<int>que;
    for(int i=1;i<=n;i++)
    {
        dist[i]=0;
    }
    dist[src]=value;
    visited[src]=true;
    que.push(src);
    while(!que.empty())
    {
        int q=que.front();
        que.pop();
        visited[q]=false;

        for(int i=head[q];i+1;i=next[i])
        {
            if(relax(q,edges[i].v,edges[i].cc,edges[i].ee)&&!visited[edges[i].v])
            {
                if(++num[edges[i].v]>n)
                    return false;
                visited[edges[i].v]=true;
                que.push(edges[i].v);
            }
        }
    }

    return true;

}
int main()
{

    scanf("%d%d%d%lf",&n,&s,&sym,&v);
    memset(head,-1,sizeof(head));
    memset(next,-1,sizeof(next));
    e=0;
    for(int i=0;i<s;i++)
    {
        scanf("%d%d%lf%lf%lf%lf",&a,&b,&ex,&ch,&ex2,&ch2);
        addNode(a,b,ch,ex);
        addNode(b,a,ch2,ex2);
    }
    if(!spfa(sym,v))
    {
        printf("YES\n");
    }
    else
        printf("NO\n");
    return 0;
}

猜你喜欢

转载自huyifan951124.iteye.com/blog/2315926