• 洛谷 P1073


    题目链接:P1073 最优贸易

    题目大意

    在一号城市开始走,一直走到n号城市,可以在路径上买东西和卖东西,使其赚的钱最大, 也可以不买不卖

    solution

    第一眼题目 (Tarjan) 缩点?写起来是不是有点长啊

    那我们呢就用分层图做吧,然后跑一个 (SPFA) (不是死了么/微笑)

    每一层的连边都为 (0) ,然后第一层想第二层连边代表买入为负的,第二层向第三层连边代表卖出,然后在与超级终点连边,总此三层,然后跑最长路

    code:

    /**
    *    Author: Alieme
    *    Data: 2020.8.30
    *    Problem: P1073
    *    Time: O()
    */
    #include <cstdio>
    #include <iostream>
    #include <string>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    #include <vector>
    
    #define ll long long
    #define rr register
    
    #define inf 1e9
    #define MAXN 100010
    
    using namespace std;
    
    inline int read() {
    	int s = 0, f = 0;
    	char ch = getchar();
    	while (!isdigit(ch)) f |= ch == '-', ch = getchar();
    	while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
    	return f ? -s : s;
    }
    
    void print(int x) {
    	if (x < 0) putchar('-'), x = -x;
    	if (x > 9) print(x / 10);
    	putchar(x % 10 + 48);
    }
    
    struct Node {
    	int v;
    	int len;
    	Node() {}
    	Node(int V, int Len) {v = V, len = Len;}
    };
    
    int n, m;
    
    int v[MAXN], d[MAXN << 2];
    
    vector<Node> G[MAXN << 2];
    
    void add(int x, int y) {
    	G[x].push_back(Node(y, 0));
    	G[x + n].push_back(Node(y + n, 0));
    	G[x + 2 * n].push_back(Node(y + 2 * n, 0));
    	G[x].push_back(Node(y + n, -v[x]));
    	G[x + n].push_back(Node(y + 2 * n, v[x]));
    }
    
    queue<int> q;
    
    bool inq[MAXN << 2];
    
    void SPFA() {
    	for (rr int i = 1; i <= n; i++) d[i] = -inf;
    	d[1] = 0;
    	inq[1] = true;
    	q.push(1);
    	while (!q.empty()) {
    		int tp = q.front();
    		q.pop();
    		inq[tp] = false;
    		int len = G[tp].size();
    		for (rr int i = 0; i < len; i++) {
    			Node x = G[tp][i];
    			if (d[x.v] < d[tp] + x.len) {
    				d[x.v] = d[tp] + x.len;
    				if (inq[x.v] == false) {
    					q.push(x.v);
    					inq[x.v] = true;
    				}
    			}
    		}
    	}
    }
    
    signed main() {
    	n = read();
    	m = read();
    	for (rr int i = 1; i <= n; i++) v[i] = read();
    	for (rr int i = 1; i <= m; i++) {
    		int x = read();
    		int y = read();
    		add(x, y);
    		int z = read();
    		if (z == 2) add(y, x);
    	}
    	G[n].push_back(Node(3 * n + 1, 0));
    	G[n * 3].push_back(Node(3 * n + 1, 0));
    	n = 3 * n + 1;
    	SPFA();
    	cout << d[n];
    }
    
  • 相关阅读:
    【Java基础】-switch支持的数据类型
    【微服务】微服务间的通信方式
    MyBatis中 #{}与${}的区别
    exeplorer-损坏的映像【错误状态0xc000012f】
    Java异常-常见的运行时异常和非运行时异常
    jvm-GC集合篇一之GC查找可回收垃圾算法
    JVM-栈的内存结构之--方法返回地址
    JVM-虚拟机栈的内部结构之局部变量表
    jvm-虚拟机栈(java栈)
    JVM-运行时数据区之---PC寄存器
  • 原文地址:https://www.cnblogs.com/lieberdq/p/13585191.html
Copyright © 2020-2023  润新知