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

    (Large extbf{Solution: } large{1.分层图\首先如果开两层,第一层到第二层表示买,第二层到第一层表示卖,会出现环或者卖卖多次的情况。\所以开三层图,第一层表示没有买,二表示买,三表示卖。然后在图上跑最长路即可。注意到边权为负,所以要写Spfa。\2.缩点+DP\首先把图中的环缩成一个点,维护每个环的最大值与最小值,然后拓扑排序即可。我感觉这种做法细节较多,不太好写。})

    (Large extbf{Code: })

    #include <bits/stdc++.h>
    #define gc() getchar() 
    #define rep(i, a, b) for (int i = (a); i <= (b); ++i)
    using namespace std;
    const int N = 1e5 + 5;
    const int M = 5e5 + 5;
    const int inf = 0x7fffffff;
    int n, m, cnt, head[N * 3 + 100], a[N], vis[N * 3 + 100], dis[N * 3 + 100];
    
    struct Edge {
    	int to, next, val;	
    }e[M * 10];
    queue<int> q;
    
    inline int read() {
    	int x = 0;
    	char ch = gc();
    	while (!isdigit(ch)) ch = gc();
    	while (isdigit(ch)) x = x * 10 + ch - '0', ch = gc();
    	return x; 
    }
    
    inline void add(int x, int y, int w) {
    	e[++cnt].to = y;
    	e[cnt].val = w;
    	e[cnt].next = head[x];
    	head[x] = cnt;
    }
    
    inline void Spfa() {
    	rep(i, 1, n * 3) dis[i] = -inf;
    	dis[1] = 0; q.push(1); vis[1] = 1;
    	while (!q.empty()) {
    		int cur = q.front(); q.pop();
    		vis[cur] = 0;
    		for (int i = head[cur]; i ; i = e[i].next) {
    			int u = e[i].to;
    			if (dis[u] < dis[cur] + e[i].val) {
    				dis[u] = dis[cur] + e[i].val;
    				if (!vis[u]) q.push(u), vis[u] = 1;
    			}
    		}
    	}
    }
    
    int main() {
    	n = read(), m = read();
    	rep(i, 1, n) a[i] = read();
    	int x, y, ju;
    	while (m--) {
    		x = read(), y = read(), ju = read();
    		add(x, y, 0); add(x + n, y + n, 0); add(x + 2 * n, y + 2 * n, 0); add(x, y + n, -a[x]); add(x + n, y + 2 * n, a[x]);
    		if (ju == 2) {
    			add(y, x, 0);
    			add(y + n, x + n, 0);
    			add(y, x + n, -a[y]);
    			add(y + n, x + 2 * n, a[y]);
    			add(y + 2 * n, x + 2 * n, 0);
    		}
    	}
    	Spfa();
    	printf("%d
    ", max(dis[n], dis[3 * n]));
    	return 0;
    } 
    

    (Large extbf{Code: })

    #include <bits/stdc++.h>
    #define gc() getchar() 
    #define rep(i, a, b) for (int i = (a); i <= (b); ++i)
    using namespace std;
    const int N = 1e5 + 5;
    const int M = 5e5 + 5;
    const int inf = 0x7fffffff;
    int n, m, cnt, id, top, vis[N], head[N], s[N], a[N], dfn[N], low[N];
    int tot, cot, ans[N], in[N], Min[N], bel[N], h[N], Max[N];
    
    struct Edge {
    	int to, next, fr;	
    }e[M];
    
    struct EDGE {
    	int to, next;	
    }E[M << 1];
    
    inline int read() {
    	int x = 0;
    	char ch = gc();
    	while (!isdigit(ch)) ch = gc();
    	while (isdigit(ch)) x = x * 10 + ch - '0', ch = gc();
    	return x; 
    }
    
    inline void add(int x, int y) {
    	e[++cnt].fr = x;
    	e[cnt].to = y;
    	e[cnt].next = head[x];
    	head[x] = cnt;
    }
    
    inline void Tarjan(int x) {
    	low[x] = dfn[x] = ++id;
    	s[++top] = x; vis[x] = 1;
    	for (int i = head[x]; i ; i = e[i].next) {
    		int u = e[i].to;
    		if (!dfn[u]) Tarjan(u), low[x] = min(low[x], low[u]);
    		else if (vis[u]) low[x] = min(low[x], dfn[u]); 
    	}
    	if (dfn[x] == low[x]) {
    		int y; ++tot;
    		while (top) {
    			y = s[top--];
    			vis[y] = 0;
    			bel[y] = tot;
    			Max[tot] = max(Max[tot], a[y]);
    			Min[tot] = min(Min[tot], a[y]);
    			if (x == y) break;
    		}
    	}
    }
    
    inline void Add(int x, int y) {
    	E[++cot].to = y;
    	E[cot].next = h[x];
    	h[x] = cot;
    }
    
    inline void DP() {
    	queue<int> q;
    	q.push(bel[1]);
    	ans[bel[1]] = max(ans[bel[1]], Max[bel[1]] - Min[bel[1]]);
    	while (!q.empty()) {
    		int x = q.front(); q.pop();
    		for (int i = h[x]; i ; i = E[i].next) {
    			int u = E[i].to;
    			--in[u];
    			Min[u] = min(Min[u], Min[x]);
    			ans[u] = max(ans[u], max(ans[x], Max[u] - Min[u]));
    			if (!in[u]) q.push(u);
    		}
    	}
    }
    
    int main() {
    	n = read(), m = read();
    	rep(i, 1, n) a[i] = read();
    	int x, y, ju;
    	while (m--) {
    		x = read(), y = read(), ju = read();
    		add(x, y);
    		if (ju == 2) add(y, x);
    	}
    	rep(i, 1, n) Min[i] = inf;
    	rep(i, 1, n) if (!dfn[i]) Tarjan(i);
    	rep(i, 1, cnt) {
    		int u = bel[e[i].fr], v = bel[e[i].to];
    		if (u != v) Add(u, v), ++in[v];
    	}
    	DP();
    	printf("%d
    ", ans[bel[n]]);
    	return 0;
    } 
    
  • 相关阅读:
    浏览器返回按钮不会触发onLoad事件
    js常用方法
    清除浮动
    Hbuilder快捷键
    页面跳转
    castapp.js颜色配置
    mui学习
    css 特殊使用技巧
    mui框架如何实现页面间传值
    从0到千万级访问量网站架构演变史
  • 原文地址:https://www.cnblogs.com/Miraclys/p/12563761.html
Copyright © 2011-2022 走看看