• P1073 最优贸易 DFS


    题目传送门

    cnblog宣传

    题意:(n)个城市,(m)条边(单向或双向)

       每个城市对于水晶球有一个价格(买的价格与卖的价格相等)

       现在从(1)走到(n),可重复经过城市,

       问能赚到的最大差价(在最小的地方买,最大的地方卖,且只进行一次买卖)

       输入边(a, b, c)表示a到b有((c=1) 单向 (c=2)双向)​边

    题解:

    在这里提供一种只用到DFS的算法

    题目可以转化为在图中找两个点权差值最大的点

    这两个点要保证从(1)(n)遍历时先遍历到点权小的点,再遍历到点权大的点。

    (maxl[i])代表从i到终点能到的最大的点

    (minl[i])代表从起点到i能走到的最小的点

    正向建图DFS求(minl)

    反向建图DFS求(maxl)

    最后(ans = max^n_{i=1}(maxl[i]-minl[i]))

    注:在建图时,采用的是一种比较特别的方式。

    将所有的边建成双向边。

    其中给不同的边附上不同的权值。

    正向边边权附(1),反向边边权附(2)

    双向边边权附(3)

    在DFS时进行判断次边是否可走即可

    code:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int N = 1e5 + 5, M = 5e5 + 5;
    int ans, z, n, m, cnt;
    int head[N], to[M], nxt[M], maxl[N], minl[N], vis[N], tag[M];
    void add(int u, int v, int t) {
    	to[++ cnt] = v;
    	tag[cnt] = t;
    	nxt[cnt] = head[u];
    	head[u] = cnt;
    }
    void dfs1(int x, int v) {
    	if(vis[x] == 1) return;
    	vis[x] = 1;
    	minl[x] = min(minl[x], v);
    	for(int i = head[x]; i ;i = nxt[i]) {
    		int v = to[i];
    		if(vis[v] == 1||tag[i] == 2) continue;
    		dfs1(v, minl[x]);
    	}
    }
    void dfs2(int x, int v) {
    	if(vis[x] == 1) return;
    	vis[x] = 1;
    	maxl[x] = max(maxl[x], v);
    	for(int i = head[x]; i ;i = nxt[i]) {
    		int v = to[i];
    		if(vis[v] == 1 || tag[i] == 1) continue;
    		dfs2(v, maxl[x]);
    	}
    	ans = max(ans, maxl[x] - minl[x]);
    }
    int main() {
    	cin >> n >> m;
    	for(int i = 1;i <= n;i ++) cin >> minl[i], maxl[i] = minl[i];
    	for(int i = 1, x, y;i <= m;i ++) {
    		cin >> x >> y >> z;
    		if(z == 1) add(x, y, 1), add(y, x, 2);
    		if(z == 2) add(x, y, 3), add(y, x, 3);
    	}
    	dfs1(1, minl[1]);
    	memset(vis, 0, sizeof(vis));
    	dfs2(n, maxl[n]);
    	cout << ans << endl;
    	return 0;
    } 
    
  • 相关阅读:
    必须了解的经典排序算法整理
    浅谈Code Review
    NOIP2018提高组省一冲奖班模测训练(六)
    NOIP2018提高组省一冲奖班模测训练(五)
    NOIP2018提高组金牌训练营——动态规划专题
    poj 3074
    搜索中的剪枝
    bitset骚操作
    NOIP 2017 宝藏
    prim求最小生成树
  • 原文地址:https://www.cnblogs.com/Paranoid-LS/p/11502622.html
Copyright © 2020-2023  润新知