题意:第一排输入n(货币的种类) m(兑换货币的站点数) t(你现在拥有的货币是第几类货币) v(你现在拥有多少该类货币)
下面每行输入的数:a b 就是a兑换b rab 兑率 cab (手续费) rba 同样的意思 (ab表示a 兑换 b)
问t币的金额经过交换最终得到的t币金额数能否增加
思路:寻找正环 果断bellman_ford算法 寻找最长的路,再进行松弛操作,每次能增加值说明有正环
tips:这题竟然是无限循环的题,还有codeblocks的功能太强大了,我调用函数的时候没有加(),它竟然能编译通过,各种坑导致这题我每次做都是错,脱了好几天最终按照别人的代码改才发现自己的错误
AC代码:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,t;
double v;
int all;
double d[120];
struct p
{
int a,b;
double r,c;
}num[220];
int Bellman_ford()
{
memset(d,0,sizeof(d));
d[t]=v;
bool flag;
for(int i=1;i<n;i++) //寻找最长路
{
flag=false;
for(int j=0;j<all;j++)
if(d[num[j].b]<(d[num[j].a]-num[j].c)*num[j].r)
{
d[num[j].b]=(d[num[j].a]-num[j].c)*num[j].r;
flag=true;
}
if(!flag)
break;
}
for(int k=0;k<all;k++) //松弛操作,看值能不能增加值
if(d[num[k].b]<(d[num[k].a]-num[k].c)*num[k].r)
return 1;
return 0;
}
int main()
{
int a,b;
double rab,rba,cba,cab;
while(cin>>n>>m>>t>>v)
{
int i;
all=0;
for(i=0;i<m;i++)
{
cin>>a>>b>>rab>>cab>>rba>>cba;
num[all].a=a;
num[all].b=b;
num[all].r=rab;
num[all++].c=cab;
num[all].a=b;
num[all].b=a;
num[all].r=rba;
num[all++].c=cba;
}
if(Bellman_ford())
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}