poj1860 spfa判断正环 Currency Exchange
——一切都回来了,用csj的话。
这货上次在群里说一道spfa判负环的题改半天,改出来的那刻觉得一切都回来了。
hh,都想起来了吗,在机房被支配的恐惧和ac的快乐。
#
觉得这个n可以用弗洛伊德,但觉得弗洛伊德维护不了那么复杂的情况
#
写了一个dij——
那么问题来了,dij的板子里有一个是vis数组,用来标记是否用过,那我这个魔改过的版本,到底是加or不加?
加的话会妨碍其他节点的更新,不加的话会变得很大很大——怎么判断大到什么程度?
#
正解是spfa(spfa你终于活了)判断正环的模板题。
有个小smart power是只要存在环,无论有无该货币点都可以,因为可以换无数次后再兑换回去,仍然是降维打击。
..一切都回来了啊。
#
以及建图的一个操作:
把货币看成点,汇率看成边;
我还在那边atm来atm去的..
-----
还没ac,但困,待填。20211005;
-----
2021 10 06 填坑
#include <iostream> #include <math.h> #include <string.h> #include <vector> #include <map> #include <queue> #include <stdio.h> #include <algorithm> #include <cstdio> using namespace std; const int maxn=5000; const double eps=1e-10; double dis[maxn],v; int t=0,n,m,s,cnt[maxn],vis[maxn],head[maxn]; struct node{ int a,b; double rab,cab,rba,cba; }atm[maxn]; struct lys{ int next,to; double c,r; }edge[maxn]; void add(int from,int to,double r,double c) { edge[++t].next=head[from]; edge[t].to=to; edge[t].c=c; edge[t].r=r; head[from]=t; } queue<int>q; int main( ) { freopen("lys.in","r",stdin); cin>>n>>m>>s>>v; for(int i=1;i<=m;i++) { scanf("%d%d%lf%lf%lf%lf",&atm[i].a,&atm[i].b,&atm[i].rab,&atm[i].cab,&atm[i].rba,&atm[i].cba); add(atm[i].a,atm[i].b,atm[i].rab,atm[i].cab); add(atm[i].b,atm[i].a,atm[i].rba,atm[i].cba); } // memset(dis,0,sizeof(dis)); for(int i=1;i<=n;i++) { dis[i]=0.0; } vis[s]=1; dis[s]=v; q.push(s); while(!q.empty( )) { int now=q.front(); q.pop(); vis[now]=0; cnt[now]++; if(cnt[now]>n) { cout<<"YES";return 0; } for(int i = head[now];i;i=edge[i].next) { int to=edge[i].to; if((dis[now]-edge[i].c)*edge[i].r-dis[to]>eps) { dis[to]=(dis[now]-edge[i].c)*edge[i].r; if(vis[to]==0) { vis[to]=1; q.push(to); } } } } cout<<"NO"; }