poj1860

/*
分析:
    最短路变异。
    求的是最大路,对每一个可以有路径返回起点的点,
设立一个limit,只要它的值>limit,那么就ok。


                                              2012-07-30 09:53
*/








#include"stdio.h"
#include"string.h"


int n,m;
int s;
double s_num;
struct A
{
	double dis;                      //求的是最大的dis
	double limit;
	int tot;
	int mem[111];
	double r[111];
	double c[111];
}E[111];


void Limit(int k)
{
	int i;
	int temp;
	int l;
	for(i=0;i<E[k].tot;i++)
	{
		temp=E[k].mem[i];
		if(E[temp].limit!=-1)	continue;
		for(l=0;l<E[temp].tot;l++)	if(E[temp].mem[l]==k)	break;
		E[temp].limit=E[k].limit/E[temp].r[l]+E[temp].c[l];
		Limit(temp);
	}
}


int SPFA()
{
	int queue[100011];
	int hash[111];
	int i;
	int key,k;
	int temp;
	double t1;
	int count=0;


	memset(hash,0,sizeof(hash));
	key=1;
	k=0;
	queue[0]=s;
	hash[s]=1;


	int yun=0;
	while(k<key)
	{
		if(count>=100000)	return 0;
		count++;
		if(E[queue[k]].dis>E[queue[k]].limit)	return 1;
		for(i=0;i<E[queue[k]].tot;i++)
		{
			temp=E[queue[k]].mem[i];
			t1=(E[queue[k]].dis-E[queue[k]].c[i])*E[queue[k]].r[i];
			if(t1>E[temp].dis)
			{
				E[temp].dis=t1;
				if(!hash[temp])
				{
					hash[temp]=1;
					queue[key++]=temp;
				}
			}
		}
		hash[queue[k++]]=0;
	}
	return 0;
}
int main()
{
	int i;
	int a,b;
	double c1,c2,c3,c4;


	while(scanf("%d%d%d%lf",&n,&m,&s,&s_num)!=-1)
	{
		///
		for(i=0;i<=n+1;i++)	E[i].tot=0;
		while(m--)
		{
			scanf("%d%d%lf%lf%lf%lf",&a,&b,&c1,&c2,&c3,&c4);
			E[a].mem[E[a].tot]=b;
			E[b].mem[E[b].tot]=a;
			E[a].r[E[a].tot]=c1;
			E[a].c[E[a].tot++]=c2;
			E[b].r[E[b].tot]=c3;
			E[b].c[E[b].tot++]=c4;
			if(a==s)
			{
				E[b].mem[E[b].tot]=n+1;
				E[b].r[E[b].tot]=c3;
				E[b].c[E[b].tot++]=c4;
				E[n+1].mem[E[n+1].tot]=b;
				E[n+1].r[E[n+1].tot]=c1;
				E[n+1].c[E[n+1].tot++]=c2;
			}
			if(b==s)
			{
				E[a].mem[E[a].tot]=n+1;
				E[a].r[E[a].tot]=c1;
				E[a].c[E[a].tot++]=c2;
				E[n+1].mem[E[n+1].tot]=a;
				E[n+1].r[E[n+1].tot]=c3;
				E[n+1].c[E[n+1].tot++]=c4;
			}
		}


		///
		for(i=0;i<=n;i++)	E[i].dis=-1;
		E[s].dis=s_num;
		E[n+1].dis=s_num;


		for(i=0;i<=n+1;i++)	E[i].limit=-1;
		E[s].limit=E[s].dis;
		Limit(s);


		if(SPFA())	printf("YES\n");
		else		printf("NO\n");
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值