[poj]poj1860(SPFA)

题目大意:有n种货币,m个交换站,每个交换站表示可以兑换两种货币,并给出相互的汇率和手续费。给出初始货币种类和数量,问是否能赚钱。

因为边都是双向的,如果从起点搜出正环,则一定能无限走这个正环然后换回起点赚钱。那么SPFA判正环即可。

#include<cstdio>
#include<iostream>
#include<queue>
using namespace std;
#define pii pair<int,int>
#define v first
#define w second 
#define ll long long
#define pb push_back
#define rep(i,n) for(int i=1;i<=n;i++)

struct edge{
    int to;
    double com,rate;
    edge(int _to,double _com,double _rate):to(_to),com(_com),rate(_rate){};
};

const int N=120;
const int inf=-(1<<30);

vector<edge> e[N];

int n,m,s,vis[N],cnt[N];

double v,dist[N];

bool spfa(int s,int n){
    rep(i,n)dist[i]=inf;
    vis[s]=1;
    dist[s]=v;
    queue<int> q;
    q.push(s);
    cnt[s]=1;
    while(!q.empty()){
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=0;i<e[u].size();i++){
            int v=e[u][i].to;
            if(e[u][i].rate*(dist[u]-e[u][i].com)>dist[v]){
                dist[v]=e[u][i].rate*(dist[u]-e[u][i].com);
                if(!vis[v]){
                    vis[v]=1;
                    q.push(v);
                    if(++cnt[v]>n)return 0;
                }
            }
        }
    }
    return 1;
}

int main(){    
    ios::sync_with_stdio(false);
    cin>>n>>m>>s>>v;
    rep(i,m){
        int u,v;
        double r1,c1,r2,c2;
        cin>>u>>v>>r1>>c1>>r2>>c2;
        e[u].pb(edge(v,c1,r1));
        e[v].pb(edge(u,c2,r2));
    }
    if(!spfa(s,n)){
        cout<<"YES";
    }
    else cout<<"NO";
} 
原文地址:https://www.cnblogs.com/xutianshu/p/10850494.html