zoukankan      html  css  js  c++  java
  • 洛谷 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];
    }
    
  • 相关阅读:
    matplotlib数据可视化之柱形图
    xpath排坑记
    Leetcode 100. 相同的树
    Leetcode 173. 二叉搜索树迭代器
    Leetcode 199. 二叉树的右视图
    Leetcode 102. 二叉树的层次遍历
    Leetcode 96. 不同的二叉搜索树
    Leetcode 700. 二叉搜索树中的搜索
    Leetcode 2. Add Two Numbers
    Leetcode 235. Lowest Common Ancestor of a Binary Search Tree
  • 原文地址:https://www.cnblogs.com/lieberdq/p/13585191.html
Copyright © 2011-2022 走看看