P1073 最优贸易
Posted olinr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1073 最优贸易相关的知识,希望对你有一定的参考价值。
题意:n个城市,m条边(单向或双向)
每个城市对于水晶球有一个价格(买的价格与卖的价格相等)
现在从1走到n,可重复经过城市,
问能赚到的最大差价(在最小的地方买,最大的地方卖)
输入边a,b,c表示a到b有(c=1 单向 c=2双向)边
找到两个点权最小,点权最大的点,保证点权小的点先遍历到!
以big[i]代表从i到终点能到的最大的点
以sma[i]代表从起点到i能走到的最小的点
正向建图跑dij求sma
反向建图跑dij求big
最后$ans=max_{i=1}^{n}(big[i]-sma[i])$
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<vector> #include<queue> using namespace std; #define nmr 105000 #define wmy 500000 #define _ 0 #define love_nmr 0 #define olinr return int big[nmr]; int val[nmr]; int sma[nmr]; vector<int> A[nmr]; vector<int> B[nmr]; struct node { int id; int dis; friend bool operator < (const node &a,const node &b) { return a.dis>b.dis; } }; struct ode { int id; int dis; friend bool operator < (const ode &a,const ode &b) { return a.dis<b.dis; } }; priority_queue<ode> p; priority_queue<node> q; int n; int m; bool vis[nmr]; inline void dij1() { memset(sma,0x3f,sizeof sma); q.push((node){1,val[1]}); sma[1]=val[1]; while(!q.empty()) { node tp=q.top(); q.pop(); if(vis[tp.id]) continue; vis[tp.id]=true; int siz=A[tp.id].size(); for(int i=0;i<siz;i++) { int go=A[tp.id][i]; sma[go]=min(sma[tp.id],val[go]); q.push((node){go,sma[go]}); } } } inline void dij2() { memset(vis,0,sizeof vis); memset(big,-0x3f,sizeof big); p.push((ode){n,val[n]}); big[n]=val[n]; while(!p.empty()) { ode tp=p.top(); p.pop(); if(vis[tp.id]) continue; vis[tp.id]=true; int siz=B[tp.id].size(); for(int i=0;i<siz;i++) { int go=B[tp.id][i]; big[go]=max(big[tp.id],val[go]); p.push((ode){go,big[go]}); } } } int main() { ios::sync_with_stdio(false); cin>>n>>m; for(int i=1;i<=n;i++) { cin>>val[i]; big[i]=sma[i]=val[i]; } for(int a,b,c,i=1;i<=m;i++) { cin>>a>>b>>c; A[a].push_back(b); B[b].push_back(a); if(c==2) { A[b].push_back(a); B[a].push_back(b); } } dij1(); dij2(); int ans=0; for(int i=1;i<=n;i++) ans=max(ans,big[i]-sma[i]); cout<<ans; olinr ~~(0^_^0)+love_nmr; }
以上是关于P1073 最优贸易的主要内容,如果未能解决你的问题,请参考以下文章