/*
有多种汇币,汇币之间可以交换,这需要手续费
货币的交换是可以重复多次的,所以我们需要找出是否存在正权回路,且最后得到的s金额是增加的
怎么找正权回路呢?(正权回路:在这一回路上,顶点的权值能不断增加即能一直进行松弛)
*/
# include <stdio.h>
# include <algorithm>
# include <string.h>
using namespace std;
struct node
{
int u;
int v;
double r;
double c;
};
node map[250];
int tot;
int id;
double num;
double dis[110];
int n;
int bellman_ford()
{
int i,j,flag;
memset(dis,0,sizeof(dis));//这里与bellman的目的刚好相反。初始化为源点到各点距离无穷小
dis[id]=num; //即bellman本用于找负环,求最小路径,本题是利用同样的思想找正环,求最大路径
for(i=1;i<=n;i++)
{
flag=0;
for(j=0;j<tot;j++)
{
if(dis[map[j].v]<(dis[map[j].u]-map[j].c)*map[j].r) //寻找最长路径
{ //进行比较的是"某点到自身的权值"和"某点到另一点的权
dis[map[j].v]=(dis[map[j].u]-map[j].c)*map[j].r;
flag=1;
}
}
if(flag==0)
break;
}
for(i=0;i<tot;i++)
{
if(dis[map[i].v]<(dis[map[i].u]-map[i].c)*map[i].r) //正环能够无限松弛
return 1;
}
return 0;
}
int main()
{
int m,a,b;
double r1,r2,c1,c2;
while(~scanf("%d%d%d%lf",&n,&m,&id,&num))
{
tot=0;
while(m--)
{
scanf("%d%d%lf%lf%lf%lf",&a,&b,&r1,&c1,&r2,&c2);
map[tot].u=a;
map[tot].v=b;
map[tot].r=r1;
map[tot++].c=c1;
map[tot].u=b;
map[tot].v=a;
map[tot].r=r2;
map[tot++].c=c2;
}
if(bellman_ford())
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
poj1860 Currency Exchange (bellman_ford)
最新推荐文章于 2020-07-23 16:56:37 发布