POJ 1860 - SPFA - 正权回路

1.Question:

我们的城市有几个货币兑换点。让我们假设每一个点都只能兑换专门的两种货币。可以有几个点,专门从事相同货币兑换。每个点都有自己的汇率,外汇汇率的A到B是B的数量你1A。同时各交换点有一些佣金,你要为你的交换操作的总和。在来源货币中总是收取佣金。

例如,如果你想换100美元到俄罗斯卢布兑换点,那里的汇率是29.75,而佣金是0.39,你会得到(100 - 0.39)×29.75=2963.3975卢布。

你肯定知道在我们的城市里你可以处理不同的货币。让每一种货币都用唯一的一个小于N的整数表示。然后每个交换点,可以用6个整数表描述:整数a和b表示两种货币,a到b的汇率,a到b的佣金,b到a的汇率,b到a的佣金。

nick有一些钱在货币S,他希望能通过一些操作(在不同的兑换点兑换),增加他的资本。当然,他想在最后手中的钱仍然是S。帮他解答这个难题,看他能不能完成这个愿望。

 

输入数据:

第一行四个数,N,表示货币的总数;M,兑换点的数目;S,nick手上的钱的类型;V,nick手上的钱的数目;1<=S<=N<=100, 1<=M<=100, V 是一个实数 0<=V<=103

接下来M行,每行六个数,整数a和b表示两种货币,a到b的汇率,a到b的佣金,b到a的汇率,b到a的佣金(0<=佣金<=102,10-2<=汇率<=102

 

输出数据:

如果nick能够实现他的愿望,则输出YES,否则输出NO。

 

样例输入:

3 2 1 20.0

1 2 1.00 1.00 1.00 1.00

2 3 1.10 1.00 1.10 1.00

 

样例输出

YES

2.Solution:

求解图的正权回路的标准问题
我们求解图的负权回路的时候利用的是边的松弛操作和SPFA的回路判断(一个点入队超过点数)
我们求解图的政权回路的时候利用的是边的放大操作和SPFA的回路判断(一个点入队超过点数)
核心在于SPFA算法在出现回路的时候如果不加限定会导致无限的入队,这样的话,我们可以根据我们的入队次数来判断的图中是否存在环

3.Code:

/*
Problem: 1860		User: lantianheyeqi
Memory: 396K		Time: 0MS
Language: C++		Result: Accepted
*/
#include"iostream"
#include"cstdio"
#include"cstring"
#include"cstdio"
#define N 105

using namespace std;

int n,m,s;
double v;
double cost[N][N];
double change[N][N];

bool SPFA()
{
	int queue[N*N];
	int head=1;
	int tail=2;
	bool book[N];
    double dis[N];
    int num[N];
    memset(book,0,sizeof(book));
    memset(num,0,sizeof(num));
    num[s]=1;
    queue[1]=s;
    book[s]=1;
    memset(dis,0,sizeof(dis));
    dis[s]=v;
    while(head!=tail)
    {
    	for(int i=1;i<=n;i++)
    	{
    		if(dis[i] < (dis[queue[head]]-cost[queue[head]][i])*change[queue[head]][i])
    		{
    			dis[i] = (dis[queue[head]]-cost[queue[head]][i])*change[queue[head]][i];
    			if(book[i]==0)
    			{
    				num[i]++; 
    				book[i]=1;
    				if(num[i]>n) return true;
    				queue[tail++]=i;
    			}
    		}
    	}
    	book[queue[head]]=0;
    	head++;
    }
    return false;
}

int main()
{
	scanf("%d%d%d%lf",&n,&m,&s,&v);
	memset(change,0,sizeof(change));
	memset(cost,0,sizeof(cost));
	for(int i=1;i<=m;i++)
	{
		int x,y;
		double change_x_y;
		double cost_x_y;
		double change_y_x;
		double cost_y_x;
		scanf("%d%d%lf%lf%lf%lf",&x,&y,&change_x_y,&cost_x_y,&change_y_x,&cost_y_x);
		cost[x][y]=cost_x_y;
		change[x][y]=change_x_y;
		cost[y][x]=cost_y_x;
		change[y][x]=change_y_x; 
	} 
	bool judge=SPFA();
	if(judge) printf("YES\n");
	else printf("NO\n");
	return 0;
}


你可能感兴趣的:(ACMer's,collection,图,POJ,专项题解)