luogu P1073 最优贸易

传送门

一上来没想出来qwq

后来Ssy说有4种做法?

(updated: Dijkstra双向广搜,缩点+dp,直接dp,spfa+分层图)

这里就说想起来最简单(同时也是最难写的)双向广搜

由于卖的点一定在买的点后面

所以我们记录一下pre[i]表示i之前最小值

suf[i]表示i之后的最大值

跑两遍dij就可以求

最后O(n)遍历求一下最大差就行

Code:

  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 }
View Code

 

posted @ 2018-11-08 11:39  白怀潇  阅读(111)  评论(0编辑  收藏  举报