spfa-poj1860

spfa详细图解:http://www.360doc.com/content/13/1208/22/14357424_335569176.shtml

此题循环将交换后变多的货币加入到队列中,结束条件是队列中没有元素或是起始货币交换后的数量已经超过了起始数量

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
int c2cnum[110];//记录从i货币有多少种交换方式
int c2cj[110][110];//记录第i货币的第n个交换方式是交换的哪种货币
double c2cr[110][110];//记录i货币第n种交换方式汇率,i从零开始
double c2cc[110][110];//记录i货币第n种交换方式的手续费,i从零开始
double d[110];
int qin[110];
queue<int> q;
int main(){
    int N,M,S;double V;
    memset(c2cnum,0,sizeof(c2cnum));
    memset(d,0,sizeof(d));
    memset(qin,0,sizeof(qin));
    cin>>N>>M>>S>>V;
    int A,B;double RAB,CAB,RBA,CBA ;
    while(M--){
        cin>>A>>B>>RAB>>CAB>>RBA>>CBA ;

        c2cr[A][c2cnum[A]]=RAB;
        c2cc[A][c2cnum[A]]=CAB;
        c2cj[A][c2cnum[A]]=B;
        c2cnum[A]++;

        c2cr[B][c2cnum[B]]=RBA;
        c2cc[B][c2cnum[B]]=CBA;
        c2cj[B][c2cnum[B]]=A;
        c2cnum[B]++;
    }
    d[S]=V;
    q.push(S);
    qin[S]=1;
    int front;
    while(q.size()){
        front=q.front();
        q.pop();
        qin[front]=0;
        for(int i=0;i<c2cnum[front];i++){
            //printf("%d %d\n",front,c2cj[front][i]);
            if(c2cr[front][i]*(d[front]-c2cc[front][i])>d[c2cj[front][i]]){
                if(qin[c2cj[front][i]]!=1){
                    q.push(c2cj[front][i]);
                    qin[c2cj[front][i]]=1;
                }
                d[c2cj[front][i]]=c2cr[front][i]*(d[front]-c2cc[front][i]);
            }
        }
        if(d[S]>V)break;
    }
    printf("%s\n",d[S]>V?"YES":"NO");
    //cin>>N>>M>>S>>V;
    return 0;
}

时间: 2024-08-11 10:11:41

spfa-poj1860的相关文章

poj1860(spfa判正环)

题目连接:http://poj.org/problem?id=1860 题意:有多种从a到b的汇率,在你汇钱的过程中还需要支付手续费,那么你所得的钱是 money=(nowmoney-手续费)*rate,现在问你有v钱,从s开始出发交换钱能不能赚钱. 分析:如何存在正环,能无限增加钱,肯定可以赚了,因此用spfa判一下即可 #include <cstdio> #include <cstring> #include <string> #include <cmath&

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

UESTC30-最短路-Floyd最短路、spfa+链式前向星建图

最短路 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的T-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? Input 输入包括多组数据. 每组数据第一行是两个整数NN ,MM (N≤100N≤100 ,M≤10000M≤1000

畅通project续HDU杭电1874【dijkstra算法 || SPFA】

http://acm.hdu.edu.cn/showproblem.php?pid=1874 Problem Description 某省自从实行了非常多年的畅通project计划后.最终修建了非常多路.只是路多了也不好,每次要从一个城镇到还有一个城镇时,都有很多种道路方案能够选择,而某些方案要比还有一些方案行走的距离要短非常多.这让行人非常困扰. 如今,已知起点和终点,请你计算出要从起点到终点.最短须要行走多少距离. Input 本题目包括多组数据.请处理到文件结束. 每组数据第一行包括两个正

HDU 2722 Here We Go(relians) Again (spfa)

Here We Go(relians) Again Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submission(s) : 1   Accepted Submission(s) : 1 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description The Gorelians

[BZOJ 1295][SCOI2009]最长距离(SPFA+暴力)

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1295 分析:很巧妙的一道spfa从搜索的角度是搜索在所有1中搜索删除哪T个1,对整个图询问,这样肯定TLE 不妨反过来想一想:对于两个点,弄出联通这两个点所需删除的最少的1,那么就知道这两个点是否可以作为题目要求的起点和终点,如果满足算一下结果和ans比较一下就可以. 所以算法就出来了: 枚举起点(S,T),用SPFA跑出图上的所有点到起点这条路径联通的最少删除的1,那么ans=max(di

poj3268 Silver Cow Party (SPFA求最短路)

其实还是从一个x点出发到所有点的最短路问题.来和回只需分别处理一下逆图和原图,两次SPFA就行了. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<map> #include<set> #include<vector> #

POJ--3259--Wormholes【SPFA判负权值回路】

题意:有n个点,之间有m条双向路径,还有w个虫洞,单向,从一点到另一点需要花费时间,但是有虫洞的话会减少时间,一个人想要走某一条路使得他能碰到过去的自己,问这个图是否能让他实现他的想法. 其实就是判一个图是否存在负权值回路,SPFA可以实现,原理是:如果存在负权值回路,那么从源点到某个顶点的距离就可以无限缩短,因此就会无限入队,所以在SPFA中统计每个顶点的入队次数,如果超过了n个(顶点个数)则说明存在负权值回路. 我把输出yes和输出no写反了,WA了两发,看了半天都没发现... #inclu

POJ 3259 Wormholes SPFA算法题解

本题其实也可以使用SPFA算法来求解的,不过就一个关键点,就是当某个顶点入列的次数超过所有顶点的总数的时候,就可以判断是有负环出现了. SPFA原来也是可以处理负环的. 不过SPFA这种处理负环的方法自然比一般的Bellman Ford算法要慢点了. #include <stdio.h> #include <string.h> #include <limits.h> const int MAX_N = 501; const int MAX_M = 2501; const

ZOJ 3794 Greedy Driver spfa

题意: 给定n个点,m条有向边,邮箱容量. 起点在1,终点在n,开始邮箱满油. 下面m行表示起点终点和这条边的耗油量(就是长度) 再下面给出一个数字m表示有P个加油站,可以免费加满油. 下面一行P个数字表示加油站的点标. 再下面一个整数Q 下面Q行 u v 表示在u点有销售站,可以卖掉邮箱里的任意数量的油,每以单位v元. 问跑到终点能获得最多多少元. 先求个每个点的最大剩余油量 f[i], 再把边反向,求每个点距离终点的最短路 dis[i]. 然后枚举一下每个销售点即可,( f[i] - dis