Currency Exchange---poj1860 ( spfa, 回路,最长路)

题目链接:http://poj.org/problem?id=1860

题解:

两种情况YES,一种是存在正权回路;

       一种是求最长路后,实现了增值,也是YES;

用spfa来判断是否存在正权回路,其实spfa是可以用来判断是否存在回路的,不管是正权还是负权,只不过它们松弛的条件不同,正权的话,我们是往dis[]权值增大的方向松弛,负权的话,我们是往dis[]权值减少的方向松弛,然后判断是否存在回路只要看有没有一点入队列的次数大于n就行了用spfa来判断是否存在正权回路,其实spfa是可以用来判断是否存在回路的,不管是正权还是负权,只不过它们松弛的条件不同,正权的话,我们是往dis[]权值增大的

如果存在一个环(从某个点出发又回到自己的路径),而且这个环上所有权值之和是负数,那这就是一个负权环,也叫负权回路;同理正权回路;

#include <iostream>
#include <cstdio>
#include <cstring>
#include <stdlib.h>
#include <math.h>
#include <queue>
#include <algorithm>
using namespace std;
#define N 210
#define INF 0xfffffff
double dist[N], V;
int cnt, Head[N], num[N], vis[N];
int n, m, s;

struct Edge
{
    int v, next;
    double r, c;
}e[N];

void Add(int u, int v, double r, double c)
{
    e[cnt].v = v;
    e[cnt].r = r;
    e[cnt].c = c;
    e[cnt].next = Head[u];
    Head[u] = cnt++;
}

bool spfa()///spfa模板;
{
    memset(vis, 0, sizeof(vis));
    memset(num, 0, sizeof(num));
    queue<int>Q;
    vis[s] = 1;
    dist[s] = V;
    Q.push(s);
    num[s]++;
    while(Q.size())
    {
        int p=Q.front();
        Q.pop();
        vis[p] = 0;
        for(int i=Head[p]; i!=-1; i=e[i].next)
        {
            int q = e[i].v;
            if(dist[q] < (dist[p] - e[i].c) * e[i].r)///注意松弛的变化;
            {
                dist[q] = (dist[p] - e[i].c) * e[i].r;
                if(!vis[q])
                {
                    vis[q] = 1;
                    Q.push(q);
                    num[q] ++;
                    if(num[q]>n)
                        return true;///存在正权回路;
                }
            }
        }

    }
    if(dist[s]>V)///最长路后,实现了增值;
        return true;
    return false;
}

int main()
{
    int a, b;
    double rab, rba, cab, cba;
    while(scanf("%d%d%d%lf", &n, &m, &s, &V)!=EOF)
    {
        cnt = 0;
        memset(Head, -1, sizeof(Head));
        memset(dist, 0, sizeof(dist));
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d%lf%lf%lf%lf", &a, &b, &rab, &cab, &rba, &cba);
            Add(a, b, rab, cab);
            Add(b, a, rba, cba);
        }
        if( spfa() )
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

时间: 2024-10-17 11:56:41

Currency Exchange---poj1860 ( spfa, 回路,最长路)的相关文章

poj 1860 Currency Exchange (SPFA、正权回路 bellman-ford)

链接:poj 1860 题意:给定n中货币,以及它们之间的税率,A货币转化为B货币的公式为 B=(V-Cab)*Rab,其中V为A的货币量, 求货币S通过若干此转换,再转换为原本的货币时是否会增加 分析:这个题就是判断是否存在正权回路,可以用bellman-ford算法,不过松弛条件相反 也可以用SPFA算法,判断经过转换后,转换为原本货币的值是否比原值大... bellman-ford    0MS #include<stdio.h> #include<string.h> str

poj 1860 Currency Exchange(SPFA)

题目链接:http://poj.org/problem?id=1860 Description Several currency exchange points are working in our city. Let us suppose that each point specializes in two particular currencies and performs exchange operations only with these currencies. There can b

HDU - 6201 transaction transaction transaction(spfa求最长路)

题意:有n个点,n-1条边的无向图,已知每个点书的售价,以及在边上行走的路费,问任选两个点作为起点和终点,能获得的最大利益是多少. 分析: 1.从某个结点出发,首先需要在该结点a花费price[a]买书,然后再在边上行走,到达目的地后,在目的地b获得price[b]. 2.因此可以建立两个虚拟结点, 虚拟结点1连向n个点,边权分别为-price[i],表示以i为起点,需花费price[i]买书. n个点连向虚拟结点2,边权分别为price[i],表示以i为终点,通过卖书可得price[i]. 3

POJ 3592--Instantaneous Transference【SCC缩点新建图 &amp;amp;&amp;amp; SPFA求最长路 &amp;amp;&amp;amp; 经典】

Instantaneous Transference Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 6177   Accepted: 1383 Description It was long ago when we played the game Red Alert. There is a magic function for the game objects which is called instantaneous

POJ 3592--Instantaneous Transference【SCC缩点新建图 &amp;&amp; SPFA求最长路 &amp;&amp; 经典】

Instantaneous Transference Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 6177   Accepted: 1383 Description It was long ago when we played the game Red Alert. There is a magic function for the game objects which is called instantaneous

POJ-1860 Currency Exchange 【spfa判负环】

Description Several currency exchange points are working in our city. Let us suppose that each point specializes in two particular currencies and performs exchange operations only with these currencies. There can be several points specializing in the

(简单) POJ 1860 Currency Exchange,SPFA判圈。

Description Several currency exchange points are working in our city. Let us suppose that each point specializes in two particular currencies and performs exchange operations only with these currencies. There can be several points specializing in the

POJ 1860: Currency Exchange 【SPFA】

套汇问题,从源点做SPFA,如果有一个点入队次数大于v次(v表示点的个数)则图中存在负权回路,能够套汇,如果不存在负权回路,则判断下源点到自身的最长路是否大于自身,使用SPFA时松弛操作需要做调整 #include<iostream> #include<cstdio> #include<string.h> #include <stdlib.h> #include <math.h> using namespace std; const int ma

Bellman_ford 算法 Currency Exchange POJ1860

Bellman_ford算法用于寻找正环或者负环! 算法导论: 24.1 The Bellman-Ford algorithm The Bellman-Ford algorithm solves the single-source shortest-paths problem in the general case in which edge weights may be negative. Given a weighted, directed graph G = (V, E) with sou

POJ - 1860 Currency Exchange(SPFA或Floyd)

题目链接:http://poj.org/problem?id=1860 题意:货币之间转换问题,有N种钱,M种转换,初始第S种钱有V价值,然后转换(转换公式:(钱价值-税)*汇率),问是否能有一种转换可以是初始S的钱价值增加. 题解: 1.SPFA 因为可能钱会减少,就是可能出现负边,所以肯定不能用dijkstra. SPFA的话就是把每种情况都搜寻一下,判断初始的钱是否增加. 2.Floyd 看到网上有人用Floyd做,用两次Floyd,找正环,就是第一次相当于赋予一个初始值,然后第二次,如果