POJ 1860Currency Exchange

题意:最短路变形题吧,就是不同种货币之间有转换关系,现在给出这种关系让你判断经过一系列转换后,回到初始货币时,能否盈利,这个需要判断是否会出现一直在一个环类不断循环,也就是会出现正环,应采用spfa,判断正环,有正环直接跳出,能盈利即可;

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<vector>
using namespace std;
typedef struct node{
	int x;int y;double r;double d;
}node;
node p[208];
int first[210];int next[210];
int vis[105];double dis[105];int ci[105];
int main(){
	int n,m,s;
	double k;
	while(scanf("%d %d %d %lf",&n,&m,&s,&k)==4){
		int a,b;
		for(int i=1;i<=m*2;i++){
			first[i]=-1;
		}
		double  c,d,e,f;
		for(int i=1;i<=m*2;i++){
			scanf("%d %d %lf %lf %lf %lf",&a,&b,&c,&d,&e,&f);
			p[i].x=a;p[i].y=b;p[i].r=c;p[i].d=d;
			next[i]=first[a];
			first[a]=i;
			i++;
			p[i].x=b;p[i].y=a;p[i].r=e;p[i].d=f;
			next[i]=first[b];
			first[b]=i;
		}
		memset(vis,0,sizeof(vis));
		memset(dis,0,sizeof(dis));
		memset(ci,0,sizeof(ci));
		queue<int>que;
		que.push(s);
		vis[s]=1;
		ci[s]++;
		dis[s]=k;
		int flag=0;
		while(!que.empty()){
			int u=que.front();
			que.pop();
			vis[u]=0;
			for(int j=first[u];j!=-1;j=next[j]){
				if(dis[p[j].y]<((dis[u]-p[j].d)*p[j].r)){
					dis[p[j].y]=((dis[u]-p[j].d)*p[j].r);
					if(vis[p[j].y]==0){
						vis[p[j].y]=1;
						ci[p[j].y]++;
						que.push(p[j].y);
						if(ci[p[j].y]>n){
							flag=1;
							break;
						}
					}
				}
			}
		}
		if(flag==1)  printf("YES
");
		else{
			if(dis[s]>k)  printf("YES
");
			else printf("NO
");
		}
	}
	return 0;
}