POJ 1860 Currency Exchange (寻找是否存在正权回路)

来源:互联网 发布:哈尔滨铁路局 知乎 编辑:程序博客网 时间:2024/06/08 18:03

传送门:http://poj.org/problem?id=1860

题目大意:给定货币转换的关系图和转换公式,问是否可以从给定的货币种类和数量,经过货币转换后回到初始的货币种类,使得数量增加。

解题思路:可以明确的知道是求是否存在一个正权的回路,修改松弛操作中的权值和关系大小,并且注意使用SPFA时不需要判断是否进队次数大于n-1次,因为并不是求是否存在负圈,加上会有问题。

Code:

/*   W          w           w        mm          mm             222222222       7777777777777    *//*    W        w w         w        m  m        m  m          222        22              7777    *//*    w        w w         w        m  m        m  m                     22              777     *//*     w      w   w       w        m    m      m    m                    22              77      *//*     w      w    w      w        m    m      m    m                 222                77      *//*      w    w      w    w        m      m    m      m              222                  77      *//*      w    w      w    w        m      m    m      m            222                    77      *//*       w  w        w  w        m        m  m        m         222                      77      *//*       w  w        w  w        m        m  m        m      222                         77      *//*        ww          ww        m          mm          m     222222222222222             77      *///#pragma comment(linker, "/STACK:102400000,102400000")//C++//int size = 256 << 20; // 256MB//char *p = (char*)malloc(size) + size;//__asm__("movl %0, %%esp\n" :: "r"(p));//G++#include<set>#include<map>#include<queue>#include<stack>#include<ctime>#include<deque>#include<cmath>#include<vector>#include<string>#include<cctype>#include<cstdio>#include<cstdlib>#include<cstring>#include<sstream>#include<iostream>#include<algorithm>#define REP(i,s,t) for(int i=(s);i<=(t);i++)#define REP2(i,t,s) for(int i=(t);i>=s;i--)using namespace std;typedef long long ll;typedef unsigned long long ull;typedef unsigned long ul;const int MAXN=105;const int INF=0x3f3f3f3f;int n,m,s;double V;double rate[MAXN][MAXN],cost[MAXN][MAXN];struct Edge{    int v;    int cost;    Edge(int _v=0,int _cost=0):v(_v),cost(_cost) {}};vector<Edge>E[MAXN];void addedge(int u,int v,int w){    E[u].push_back(Edge(v,w));}bool vis[MAXN];//在队列标志int cnt[MAXN];//每个点的入队列次数double dist[MAXN];bool SPFA(int start,int n){    memset(vis,false,sizeof(vis));    memset(dist,0,sizeof(dist));    vis[start]=true;    dist[start]=V;    queue<int>que;    while(!que.empty())que.pop();    que.push(start);    memset(cnt,0,sizeof(cnt));    cnt[start]=1;    while(!que.empty())    {        int u=que.front();        que.pop();        vis[u]=false;        for(int i=1; i<=n; i++)        {            int v=i;            if(dist[v]<(dist[u]-cost[u][v])*rate[u][v])            {                dist[v]=(dist[u]-cost[u][v])*rate[u][v];                if(dist[start]>V)                {                    return true;                }                if(!vis[v])                {                    vis[v]=true;                    que.push(v);                }            }        }    }    return false;}int main(){#ifdef ONLINE_JUDGE#else    freopen("test.in","r",stdin);#endif    while(~scanf("%d%d%d%lf",&n,&m,&s,&V))    {        REP(i,1,n)        {            REP(j,1,n)            {                if(i==j)                {                    rate[i][j]=1;                }                else                {                    rate[i][j]=0;                }                cost[i][j]=0;            }        }        int u,v;        double rab,cab,rba,cba;        REP(i,1,m)        {            scanf("%d%d%lf%lf%lf%lf",&u,&v,&rab,&cab,&rba,&cba);            rate[u][v]=rab;            rate[v][u]=rba;            cost[u][v]=cab;            cost[v][u]=cba;        }        printf("%s\n",SPFA(s,n)?"YES":"NO");    }    return 0;}
0 0