luogu P1073 最优贸易
一上来没想出来qwq
后来Ssy说有4种做法?
(updated: Dijkstra双向广搜,缩点+dp,直接dp,spfa+分层图)
这里就说想起来最简单(同时也是最难写的)双向广搜
由于卖的点一定在买的点后面
所以我们记录一下pre[i]表示i之前最小值
suf[i]表示i之后的最大值
跑两遍dij就可以求
最后O(n)遍历求一下最大差就行
Code:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<queue> 6 #include<vector> 7 #define pr pair<int,int> 8 #define mp make_pair 9 #define rep(i,a,n) for(int i = a;i <= n;i++) 10 #define per(i,n,a) for(int i = n;i >= a;i--) 11 #define ms(a,b) memset(a,b,sizeof a) 12 #define inf 2147483647 13 using namespace std; 14 typedef long long ll; 15 ll read() { 16 ll as = 0,fu = 1; 17 char c = getchar(); 18 while(c < '0' || c > '9') { 19 if(c == '-') fu = -1; 20 c = getchar(); 21 } 22 while(c >= '0' && c <= '9') { 23 as = as * 10 + c - '0'; 24 c = getchar(); 25 } 26 return as * fu; 27 } 28 29 const int N = 200005; 30 //head 31 int n,m,ans,a[N]; 32 int head[N],mo[N],nxt[N],cnt; 33 void add(int x,int y) { 34 mo[++cnt] = y; 35 nxt[cnt] = head[x]; 36 head[x] = cnt; 37 return; 38 } 39 40 int Head[N],Mo[N],Nxt[N],Cnt; 41 void Add(int x,int y) { 42 Mo[++Cnt] = y; 43 Nxt[Cnt] = Head[x]; 44 Head[x] = Cnt; 45 return; 46 } 47 48 int dis[N],Dis[N]; 49 bool vis[N],Vis[N]; 50 void dij(int s) { 51 rep(i,1,n) dis[i] = inf; 52 dis[s] = a[s]; 53 priority_queue<pr ,vector<pr>, greater<pr> > q; 54 q.push(mp(dis[s],s)); 55 while(!q.empty()) { 56 int x = q.top().second; 57 q.pop(); 58 if(vis[x]) continue; 59 vis[x] = 1; 60 for(int i = head[x];i;i = nxt[i]) { 61 int sn = mo[i]; 62 if(dis[sn] > min(dis[x],a[sn])) { 63 dis[sn] = min(dis[x],a[sn]); 64 q.push(mp(dis[sn],sn)); 65 } 66 } 67 } 68 return; 69 } 70 71 void Dij(int s) { 72 Dis[s] = a[s]; 73 priority_queue<pr> q; 74 q.push(mp(Dis[s],s)); 75 while(!q.empty()) { 76 int x = q.top().second; 77 q.pop(); 78 if(Vis[x]) continue; 79 Vis[x] = 1; 80 for(int i = Head[x];i;i = Nxt[i]) { 81 int sn = Mo[i]; 82 if(Dis[sn] < max(Dis[x],a[sn])) { 83 Dis[sn] = max(Dis[x],a[sn]); 84 q.push(mp(Dis[sn],sn)); 85 } 86 } 87 } 88 return; 89 } 90 int main() { 91 n = read(); 92 m = read(); 93 rep(i,1,n) a[i] = read(); 94 rep(i,1,m) { 95 int x = read(); 96 int y = read(); 97 int z = read(); 98 add(x,y),Add(y,x); 99 if(z == 2) Add(x,y),add(y,x); 100 } 101 dij(1),Dij(n); 102 rep(i,1,n) ans = max(ans,Dis[i] - dis[i]); 103 printf("%d\n",ans); 104 return 0; 105 }
> 别忘了 总有人在等着你