zoukankan      html  css  js  c++  java
  • 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
    ",ans);
    104     return 0;
    105 }
    View Code
    > 别忘了 总有人在等着你
  • 相关阅读:
    vnode之update 还是没太懂
    vnodec创建之标签
    1054 求平均值
    1053 住房空置率
    1052 卖个萌
    1051 复数乘法
    1050 螺旋矩阵
    1049 数列的片段和
    1048 数字加密
    1047 编程团体赛
  • 原文地址:https://www.cnblogs.com/yuyanjiaB/p/9928138.html
Copyright © 2011-2022 走看看