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;
}

 

posted @ 2018-08-16 17:26  olinr  阅读(174)  评论(0编辑  收藏  举报