//题意:给出有向图,有环(SCC),每个节点有一个 商品值 ,小明想从1点走向n点,同时想要进行一次贸易,即从路线上某个点买入商品, 又在某个节点卖出, 询问最大收益是多少(如果收益为负数那么输出0) //思路:有环第一时间想到tarjan缩点,重建一幅无环有向图 // 因为我想取得最大收益,所以在到达一个点时,我应该用路径上的最小价进货,同时看在这点卖出是否能取得最大值,是一个dp问题(用前点更新后点) // 注释内是用的dfs序跑dp,但是会T掉几个点,具体的情况实在无法想象出来 // 所以为了保险起见,跑dp这种需要前提条件来更新后面条件的有序结构,要使用拓扑序 // 另外缩点会有重边问题,本题无影响,但是其他题要视具体情况考虑 // #include<bits/stdc++.h> using namespace std; const int N = 1e5 + 10; vector<int> mp[N], mp2[2 * N]; int n, m, wt[N]; int dfn[N], low[N], ins[N], bel[N], idx, cnt;//dfn序,low值,是否存在,哪个强联通分量(缩点用) stack<int> stk; int dp[N]; map<pair<int, int>, bool> ct; struct point { int in, out; }fmp[2 * N]; void dfs(int u) { dfn[u] = low[u] = ++idx; ins[u] = true; stk.push(u); for (auto v : mp[u]) { if (!dfn[v]) dfs(v); if (ins[v]) low[u] = min(low[u], low[v]); } if (dfn[u] == low[u]) { ++cnt; int maxn = -1e9, minn = 1e9; while (true) { int v = stk.top(); maxn = max(maxn, wt[v]); minn = min(minn, wt[v]); ins[v] = false; bel[v] = cnt; stk.pop(); if (u == v) break; } fmp[cnt].in = minn; fmp[cnt].out = maxn; } } /*void dfs2(int x) { for (auto y : mp2[x]) { if (fmp[y].in > fmp[x].in) fmp[y].in = fmp[x].in; dp[y] = max(dp[y], max(dp[x], fmp[y].out - fmp[y].in)); dfs2(y); } }*/ int rd[2 * N]; void solve() { queue<int> st; st.push(bel[1]); while (!st.empty()) { int x = st.front(); st.pop(); for (auto y : mp2[x]) { if (fmp[y].in > fmp[x].in) fmp[y].in = fmp[x].in; dp[y] = max(dp[y], max(dp[x], fmp[y].out - fmp[y].in)); rd[y]--; if (rd[y] == 0) st.push(y); } } } int main() { cin >> n >> m; cnt = n; for (int i = 1; i <= n; i++) cin >> wt[i]; for (int i = 1; i <= m; i++) { int a, b, od; cin >> a >> b >> od; mp[a].push_back(b); if (od == 2) mp[b].push_back(a); } dfs(1); for (int i = 1; i <= n; i++) { for (auto x : mp[i]) { if (bel[x] == bel[i]) continue; if (ct[{bel[x], bel[i]}] || ct[{bel[i], bel[x]}]) continue; ct[{bel[x], bel[i]}] = ct[{bel[i], bel[x]}] = true; rd[bel[x]]++; mp2[bel[i]].push_back(bel[x]); } } //dfs2(bel[1]); solve(); cout << dp[bel[n]]; return 0; }
标签:缩点,cnt,int,NOIP2009,fmp,st,low,P1073,dp From: https://www.cnblogs.com/Aacaod/p/17034828.html