poj1860 Currency Exchange (bellman_ford)

来源:互联网 发布:java解析excel文件 编辑:程序博客网 时间:2024/05/20 16:09
/*有多种汇币,汇币之间可以交换,这需要手续费货币的交换是可以重复多次的,所以我们需要找出是否存在正权回路,且最后得到的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;}

0 0
原创粉丝点击