POJ 1860 Currency Exchange spfa
阿新 • • 發佈:2019-01-27
注意,使用spfa演算法的時候,一個點進隊n+2次說明所有與其相關的點均已經得到了正環的收益,然而除此之外什麼都不能說明,在這道題上,也就不可能說明此時某點的值是否可以大於它的初始值。spfa是個神奇的演算法,的空一定要好好研究一番。
#include<iostream> #include<cstdio> #include<string.h> #include<algorithm> #include<queue> using namespace std; struct Edge { int to,nex; double c,r; }edge[220]; int e,head[110],inq[110],vis[110],n,m,s; double v,d[110]; void addedge(int a,int b,double rr,double cc) { edge[e].to=b; edge[e].r=rr; edge[e].c=cc; edge[e].nex=head[a]; head[a]=e++; //cout<<"a="<<a<<" b="<<b<<" r="<<rr<<" c="<<cc<<endl; } int spfa(int s) { queue<int> q; memset(inq,0,sizeof(inq)); memset(vis,0,sizeof(vis)); memset(d,0,sizeof(d)); d[s]=v; inq[s]=1; q.push(s); int tmp=s; while (!q.empty()) { s=q.front(); q.pop(); vis[s]++; inq[s]=0; //cout<<"s="<<s<<" vis="<<vis[s]<<endl; if (d[tmp]>v) return true; if (vis[s]==n+2) continue; for (int i=head[s]; i!=-1; i=edge[i].nex) { int v=edge[i].to; //cout<<"s="<<s<<" v="<<v<<" d="<<d[v]<<" d2="<<(d[s]-edge[i].c)*edge[i].r<<endl; //cout<<"ds="<<d[s]<<" c="<<edge[i].c<<" r="<<edge[i].r<<endl; if (d[v]<(d[s]-edge[i].c)*edge[i].r) { d[v]=(d[s]-edge[i].c)*edge[i].r; if (!inq[v]) { inq[v]=1; q.push(v); } } //if (d[tmp]>v) return true; } } return false; } int main() { while (~scanf("%d%d%d%lf",&n,&m,&s,&v)) { e=0; memset(head,-1,sizeof(head)); for (int i=1; i<=m; i++) { int a,b; double rab,cab,rba,cba; scanf("%d%d%lf%lf%lf%lf",&a,&b,&rab,&cab,&rba,&cba); addedge(a,b,rab,cab); addedge(b,a,rba,cba); } if (spfa(s)) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }