POJ1860 Currency Exchange 最短路Bellman Ford變形

這道題一看應該就是判環,然後就不會了QAQ...看了網上說的,只要判斷是否有正環,那麼循環無數次之後一定可以賺回本錢。說實話bellman_ford算法我用的不多。。這次也是懵逼了。。參考博客是kuangbin的Orz:https://www.cnblogs.com/kuangbin/archive/2012/08/17/2644807.html

正環是剛好和板子反的,注意點都在代碼裏了,AC代碼如下:

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
const int INF=0x3f3f3f3f;

const int MAX=105;
int n,m,s;
double vv;
struct Edge
{
    int u,v;
    double r,c;
}e[MAX*2];//注意×2!!!
int tol;
void addedge(int u,int v,double r,double c)
{
    e[tol].u=u;e[tol].v=v;e[tol].r=r;e[tol++].c=c;
}

double dis[MAX];//注意double!
bool bellman_ford(int st,double num)
{
    memset(dis,0,sizeof(dis));
    dis[st]=num;//注意!!!!!!
    for(int k=1;k<n;k++)//n-1次
    {
        bool flag=false;
        for(int i=0;i<tol;i++)
        {
            int u=e[i].u,v=e[i].v;
            double r=e[i].r,c=e[i].c;
            if(dis[v]<(dis[u]-c)*r) //求最大
            {
                flag=true;
                dis[v]=(dis[u]-c)*r;
            }
        }
        if(!flag) return true;//沒有迴路
    }
    for(int i=0;i<tol;i++)
    {
        int u=e[i].u,v=e[i].v;
        double r=e[i].r,c=e[i].c;
        if(dis[v]<(dis[u]-c)*r)
            return false;//有迴路
    }
    return true;
}
int main()
{
    while(scanf("%d%d%d%lf",&n,&m,&s,&vv)==4)
    {
        tol=0;
        int u,v;//注意區別v和vv!!!!!!!!
        double r,c;//注意double!
        for(int i=0;i<m;i++)
        {
            scanf("%d%d",&u,&v);
            scanf("%lf%lf",&r,&c);
            addedge(u,v,r,c);
            scanf("%lf%lf",&r,&c);
            addedge(v,u,r,c);
        }
        if(bellman_ford(s,vv)) printf("NO\n");
        else printf("YES\n");
    }
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章