zoukankan      html  css  js  c++  java
  • Luogu P1073 最优贸易

    传送门

    在图上进行一次买,一次卖,使最后的获利最大。

    可以看出,在一个节点x上,有两种选择:不买卖;买(当前没买)或卖(当前买了)。

    把没买的状态记为状态x1,买了记为状态x2,买完又卖了记为状态x3。

    在每个点上,可以由x1转到x2,x2转到x3,并且操作是一次性的。

    考虑分层最短路,dis[x]表示到点x的花费。

    把x1-x2连边,边权为w[x];x2-x3连边,边权为-w[x]。

    再把相邻的点x1-y1,x2-y2,x3-y3分别连边,边权为0。

    最后跑最短路就可以了。因为有负权边,所以要用SPFA。

    代码如下

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #define MogeKo qwq
    #include<queue>
    using namespace std;
    const int maxn = 2e6;
    const int INF = 0x3f3f3f3f;
    int n,m,x,y,z,cnt;
    int head[maxn],to[maxn],nxt[maxn],val[maxn];
    int w[maxn],dis[maxn];
    bool vis[maxn];
    
    void add(int x,int y,int z) {
        to[++cnt] = y;
        nxt[cnt] = head[x];
        head[x] = cnt;
        val[cnt] = z;
    }
    
    void addedge(int x,int y){
        add(x,y,0);
        add(x+n,y+n,0);
        add(x+n+n,y+n+n,0);
    }
    
    void spfa(int s) {
        queue <int> q;
        dis[s] = 0;
        q.push(s);
        vis[s] = true;
        while(!q.empty()) {
            int u = q.front();
            q.pop();
            vis[u] = false;
            for(int i = head[u]; i; i = nxt[i]) {
                int v = to[i];
                if(vis[v])continue;
                if(dis[u] + val[i] >= dis[v])continue;
                dis[v] = dis[u] + val[i];
                q.push(v);
                vis[v] = true;
            }
        }
    }
    
    int main() {
        scanf("%d%d",&n,&m);
        for(int i = 1; i <= n; i++) {
            scanf("%d",&w[i]);
            add(i,i+n,w[i]);
            add(i+n,i+n+n,-w[i]);
            dis[i] = dis[i+n] = dis[i+n+n] = INF;
        }
        for(int i = 1; i <= m; i++) {
            scanf("%d%d%d",&x,&y,&z);
            addedge(x,y);
            if(z == 2) addedge(y,x);
        }
        spfa(1);
        printf("%d",max(0,-dis[n+n+n]));
        return 0;
    }
    View Code
  • 相关阅读:
    Max History CodeForces
    Buy a Ticket CodeForces
    AC日记——字符串的展开 openjudge 1.7 35
    AC日记——回文子串 openjudge 1.7 34
    AC日记——判断字符串是否为回文 openjudge 1.7 33
    AC日记——行程长度编码 openjudge 1.7 32
    AC日记——字符串P型编码 openjudge 1.7 31
    AC日记——字符环 openjudge 1.7 30
    AC日记——ISBN号码 openjudge 1.7 29
    AC日记——单词倒排 1.7 28
  • 原文地址:https://www.cnblogs.com/mogeko/p/10932513.html
Copyright © 2011-2022 走看看