题目大意:给顶每条边的汇率和所花费的手续费,让你求是否会比原来的钱多。
算法思想:spfa的变形,只需要判断是否存在正环即可,但要注意精度问题,又在这精度上wa了好几次,还是太粗心了。
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; int n,s,sym; double v; int a,b,e; double ex,ch,ex2,ch2; bool visited[300]; int head[300],next[300]; double dist[300]; int num[300]; typedef struct Edge { int u; int v; double cc; double ee; }; Edge edges[300]; void addNode(int u,int v,double cc,double ee) { edges[e].u=u; edges[e].v=v; edges[e].cc=cc; edges[e].ee=ee; next[e]=head[u]; head[u]=e++; } bool relax(int u,int v,double cc,double ee) { if(dist[v]<(dist[u]-cc)*ee) { dist[v]=(dist[u]-cc)*ee; return true; } return false; } bool spfa(int src,double value) { memset(num,0,sizeof(num)); memset(visited,false,sizeof(visited)); queue<int>que; for(int i=1;i<=n;i++) { dist[i]=0; } dist[src]=value; visited[src]=true; que.push(src); while(!que.empty()) { int q=que.front(); que.pop(); visited[q]=false; for(int i=head[q];i+1;i=next[i]) { if(relax(q,edges[i].v,edges[i].cc,edges[i].ee)&&!visited[edges[i].v]) { if(++num[edges[i].v]>n) return false; visited[edges[i].v]=true; que.push(edges[i].v); } } } return true; } int main() { scanf("%d%d%d%lf",&n,&s,&sym,&v); memset(head,-1,sizeof(head)); memset(next,-1,sizeof(next)); e=0; for(int i=0;i<s;i++) { scanf("%d%d%lf%lf%lf%lf",&a,&b,&ex,&ch,&ex2,&ch2); addNode(a,b,ch,ex); addNode(b,a,ch2,ex2); } if(!spfa(sym,v)) { printf("YES\n"); } else printf("NO\n"); return 0; }