Optimal trade (shortest path)

Insert picture description here

Idea: What we require is the maximum price difference. Then, for example, when we trade at K, we buy the crystal ball with the lowest price from 1 to K, and we sell it at the highest price from K to N. Then we will run the shortest path from 1-N once, the shortest update condition is the lowest price of the crystal ball, and then run the shortest path from KN from the reverse direction, and the update condition is the most expensive price of the crystal ball. Then enumerate K to calculate the maximum spread

#pragma GCC optimize(2)
#include<bits/stdc++.h>
 
using namespace std;
typedef long long ll;
#define SIS std::ios::sync_with_stdio(false)
#define space putchar(' ')
#define enter putchar('\n')
#define lson root<<1
#define rson root<<1|1
typedef pair<int,int> PII;
typedef pair<int,PII> PIII;
const int mod=1e9+7;
const int N=2e6+5;
const int inf=0x7f7f7f7f;

int gcd(int a,int b)
{
    
    
    return b==0?a:gcd(b,a%b);
}
 
ll lcm(ll a,ll b)
{
    
    
    return a*(b/gcd(a,b));
}
 
template <class T>
void read(T &x)
{
    
    
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
        if(c == '-')
            op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
        x = x * 10 + c - '0';
    if(op)
        x = -x;
}
template <class T>
void write(T x)
{
    
    
    if(x < 0)
        x = -x, putchar('-');
    if(x >= 10)
         write(x / 10);
    putchar('0' + x % 10);
}
ll qsm(int a,int b,int p)
{
    
    
    ll res=1%p;
    while(b)
    {
    
    
        if(b&1)
            res=res*a%p;
        a=1ll*a*a%p;
        b>>=1;
    }
    return res;
}
struct node
{
    
    
    int to,nex;
}edge[N];
int tot,bcnt;
int n,m;
int w[N];
int h1[N],h2[N];
int dismin[N],dismax[N];
int vis[N];

void add(int u,int v,int head[])
{
    
    
    edge[tot].to=v;
    edge[tot].nex=head[u];
    head[u]=tot++;
}
void spfa(int head[],int dis[],int type)
{
    
    
    queue<int> q;
    if(type==0)
    {
    
    
        memset(dis,inf,sizeof dismin);
        dis[1]=w[1];
        q.push(1);
    }else{
    
    
        memset(dis,-inf,sizeof dismax);
        dis[n]=w[n];
        q.push(n);
    }
    while(q.size())
    {
    
    
        int t=q.front();
        q.pop();
        vis[t]=0;
        for(int i=head[t];~i;i=edge[i].nex)
        {
    
    
            int v=edge[i].to;
            if(type==0&&dis[v]>min(dis[t],w[v])||type==1&&dis[v]<max(dis[t],w[v]))
            {
    
    
                if(type==0)
                dis[v]=min(dis[t],w[v]);
                else
                dis[v]=max(dis[t],w[v]);
                if(!vis[v])
                {
    
    
                    q.push(v);
                    vis[v]=1;
                }
            }
        }
    }
}





int main()
{
    
    
    memset(h1,-1,sizeof h1);
    memset(h2,-1,sizeof h2);

   scanf("%d%d",&n,&m);
   for(int i=1;i<=n;i++)
   {
    
    
       scanf("%d",&w[i]);
   }
   while(m--)
   {
    
    
       int a,b,c;
       scanf("%d%d%d",&a,&b,&c);
       add(a,b,h1);add(b,a,h2);
       if(c==2){
    
    
           add(b,a,h1);
           add(a,b,h2);
       }

   }
   spfa(h1,dismin,0);
   spfa(h2,dismax,1);
   int res=0;
   for(int i=1;i<=n;i++)res=max(res,dismax[i]-dismin[i]);
   printf("%d",res);
   
   return 0;

}


Guess you like

Origin blog.csdn.net/qq_43619680/article/details/112917952