zoukankan      html  css  js  c++  java
  • POJ1860 Currency Exchange bellman

    该题是给定某一货币,然后再给定一些兑换的条件,问能否使得钱币总数增加,是不是非常诱人呢?

    对该题的一个转化就是如果在转化的过程中出现了环的话,那么我们就可以在这个环内不停的进行转化,以致钱币数量无穷大,再反过来兑换就可以得到原始的币种了,而且一定会增加。

    利用bellman算法能过得到是否存在环,由于最长的环的路径长度是N-1(N各节点)所以我们只要对所有的边进行N-1次松弛,然后再看是否还可以继续松弛来判断是否有环的形成。

    代码如下:

    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #define MAXN 205
    using namespace std;
    
    int N, M, S, cnt;
    double V, dis[MAXN];
    
    struct edge
    {
        int a, b;
        double r, c;    
    }e[MAXN];
     
    bool bellman()
    {
        memset(dis, 0, sizeof (dis));
        memset(hash, 0, sizeof (hash));
        dis[S] = V;
        hash[S] = 1;
        for (int j = 1; j <= N-1; ++j) {
            for (int i = 1; i <= cnt; ++i) { // 遍历所有的边  
                if ((dis[ e[i].a ]-e[i].c)*e[i].r - dis[ e[i].b ] > 1e-6) { 
                    dis[ e[i].b ]= (dis[ e[i].a ]-e[i].c)*e[i].r;
             // 不能够在此处进行visit判断是否成环,因为可能在一次更新中更新两次 } } }
    for (int i = 1; i <= cnt; ++i) { if ((dis[ e[i].a ]-e[i].c)*e[i].r - dis[ e[i].b ] > 1e-6) { return 1; } } return 0; } int main() { int a, b; double rab, cab, rba, cba; while (scanf("%d %d %d %lf", &N, &M, &S, &V) == 4) { cnt = 0; for (int i = 0; i < M; ++i) { scanf("%d %d %lf %lf %lf %lf", &a, &b, &rab, &cab, &rba, &cba); ++cnt; e[cnt].a = a, e[cnt].b = b, e[cnt].r = rab, e[cnt].c = cab; ++cnt; e[cnt].a = b, e[cnt].b = a, e[cnt].r = rba, e[cnt].c = cba; } printf(bellman()? "YES\n":"NO\n"); } }
  • 相关阅读:
    随笔——关于读论文
    enumerate
    torch.max
    C# WPF侧边栏导航菜单(Dropdown Menu)
    C# WPF过渡效果实现(C# WPF Material Design UI: Transitions)
    用C# WPF简单实现仪表控件
    自定义滚动条(Custom ScrollBar)
    从头实现一个WPF条形图
    漂亮的无序列表样式
    C# WPF实用的注册窗体
  • 原文地址:https://www.cnblogs.com/Lyush/p/2571102.html
Copyright © 2011-2022 走看看