最短路中汇率问题 POJ 1860 与 POJ 2240

http://poj.org/problem?id=1860

题目大意:给你一系列货币之间的汇率,有人持有一种货币,经过多次交换后能不能得到更多的钱,这个可以用spfa做,但是我还是用dijkstra做的,用了spfa的一点思想:当一个点被更新后,它要放入能更新周围点的这个队列中

#include<stdio.h>
#include<string.h>

float r[1000][1000],c[1000][1000],f[1000];
int k[1000];

int main()
{
	int N,M,S;
      float t;
	scanf("%d%d%d%f",&N,&M,&S,&t);
	   int i;
	   for(i=1;i<=N;i++)
         f[i]=0;
	   f[S]=t;
       memset(r,0,sizeof(r));
	   memset(c,0,sizeof(c));
	   for(i=1;i<=M;i++)
	   {
		   int a,b;
		   scanf("%d%d",&a,&b);
             scanf("%f%f%f%f",&r[a][b],&c[a][b],&r[b][a],&c[b][a]);
	   }
	   memset(k,0,sizeof(k));
	   while(1)//dijkstra部分
	   {
		   int judge=-1;
		   for(i=1;i<=N;i++)
			   if(k[i]==0)
			   {
				   if(judge==-1||f[judge]<f[i])
					   judge=i;
			   }
			   if(judge==-1)
				   break;
			   k[judge]=1;
		   for(i=1;i<=N;i++)
		   {
			   if(r[judge][i]>0&&(f[judge]-c[judge][i])*r[judge][i]>f[i])
			   {
				   f[i]=(f[judge]-c[judge][i])*r[judge][i];
				   k[i]=0;//就是这里,如果它被更新了,从删除状态恢复,下次继续更新周围的点
			   }
		   }
		   if(f[S]>t)//如果s点大于之前的值,直接break;
			   break;
	   }
	  if(f[S]>t)
		  printf("YES\n");
	     else
			 printf("NO\n");
		 return 0;
}



http://poj.org/problem?id=2240 

跟上面的一个意思,只不过输入的字符串所代表的的货币你要自己一个个来构图,别的就没什么了

#include<stdio.h>
#include<string.h>

char str1[1000][1000], str2[2000][1000],str3[2000][1000];//这边要数组开的很大才能过,不知道为什么,我的小伙伴们开的很小就过了,如果有人能告诉我原因,我会感激涕零的,诶、、、、、、说多了都是泪啊!!!!
float d[1000][1000],f[1000];
int  k[100];
int main()
{
	
	int n,m,cases=0;
	while(scanf("%d",&n)!=EOF&&n!=0)
	{
		int i,j;
	    memset(d,0,sizeof(d));
		for(i=1;i<=n;i++)
		{
				getchar();
				scanf("%s",str1[i]);
		}
		for(i=1;i<=n;i++)
			d[i][i]=1;
		scanf("%d",&m);
		for(i=1;i<=m;i++)
		{
			int a,b;
			float t;
			 getchar();
			 scanf("%s%f%s",str2[i],&t,str3[i]);
			 for(j=1;j<=n;j++)
			 {
				if(strcmp(str2[i],str1[j])==0)
		    	    a=j; 
				if(strcmp(str3[i],str1[j])==0)
                    b=j;
			 }
			 d[a][b]=t;
			// printf("%f ",d[a][b]);
		}

       memset(k,0,sizeof(k));

	   for(i=2;i<=n;i++)
		   f[i]=0;
	   f[1]=1;
        // printf("sdfg\n");
		while(1)
		{
			int judge=-1;
			for(i=1;i<=n;i++)
				if(k[i]==0)
				{
					if(judge==-1||f[judge]<f[i])
						judge=i;
				}
			k[judge]=1;
			if(judge==-1)
				break;
		    for(i=1;i<=n;i++)
			{
				if(d[judge][i]>0&&f[i]<d[judge][i]*f[judge])
				{
					f[i]=d[judge][i]*f[judge];
					k[i]=0;
				}
			}
			if(f[1]>1)
				break;
			//printf("df\n");
		}
		cases++;
	//	for(i=2;i<=n;i++)
	//		if(f[i]*d[i][1]>1)
		if(f[1]>1)	
			printf("Case %d: Yes\n",cases);
	//	if(i==n+1)
			else
				printf("Case %d: No\n",cases);

	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值