[NOIP 2009]最优贸易

题目传送门

此题主要考察的是思想,可以借助最短路的思想去做,我写的是dijkstra,通过每次找中间点的方式,两次操作(请读者慢慢思考)

而两次操作一次跑的是题目上给的边,第二次跑的是反向边,请读者好好思考

而既然借助dijkstra的思想,每次找点,请注意,此坑本作者语文能力有限,无法讲解

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
inline int read()
{
    int f=1,ans=0;char c;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
    return ans*f;
}
int n,m,s[100001],dis1[100001],dis2[100001],head1[100001],head2[100001],cnt1,cnt2,vis1[100001],vis2[100001];
struct node{
    int u,v,nex;
}x1[1000001];
struct node1{
    int u,v,nex;
}x2[1000001];
void add1(int u,int v)
{
    x1[cnt1].u=u,x1[cnt1].v=v,x1[cnt1].nex=head1[u],head1[u]=cnt1++;
    swap(u,v);
    x2[cnt2].u=u,x2[cnt2].v=v,x2[cnt2].nex=head2[u],head2[u]=cnt2++;
}
void add2(int u,int v)
{
    x1[cnt1].u=u,x1[cnt1].v=v,x1[cnt1].nex=head1[u],head1[u]=cnt1++;
    swap(u,v);
    x1[cnt1].u=u,x1[cnt1].v=v,x1[cnt1].nex=head1[u],head1[u]=cnt1++;
    swap(u,v);
    x2[cnt2].u=u,x2[cnt2].v=v,x2[cnt2].nex=head2[u],head2[u]=cnt2++;
    swap(u,v);
    x2[cnt2].u=u,x2[cnt2].v=v,x2[cnt2].nex=head2[u],head2[u]=cnt2++;
}
priority_queue<pair< int , int > > que1;
priority_queue<pair< int , int > > que2;
int main()
{
    memset(head1,-1,sizeof(head1)),memset(head2,-1,sizeof(head2));
    n=read(),m=read();
    for(int i=1;i<=n;i++) s[i]=read(); 
    for(int i=1;i<=m;i++)
    {
        int u=read(),v=read(),w=read();
        if(w==1) add1(u,v);
        else add2(u,v);
    }
    dis1[1]=s[1];
    que1.push(make_pair(0,1));
    while(!que1.empty())
    {
        int xx=que1.top().second;que1.pop();
        if(vis1[xx]==1) continue;
        vis1[xx]=1;
        for(int i=head1[xx];i!=-1;i=x1[i].nex)
        {
            que1.push(make_pair(-min(dis1[x1[i].u],s[x1[i].v]),x1[i].v));
            dis1[x1[i].v]=min(dis1[x1[i].u],s[x1[i].v]);
        }
    }
    dis2[n]=s[n];
    que2.push(make_pair(0,n));
    while(!que2.empty())
    {
        int xx=que2.top().second;que2.pop();
        if(vis2[xx]==1) continue;
        vis2[xx]=1;
        for(int i=head2[xx];i!=-1;i=x2[i].nex)
        {
            que2.push(make_pair(-max(dis2[x2[i].u],s[x2[i].v]),x2[i].v));
            dis2[x2[i].v]=max(dis2[x2[i].u],s[x2[i].v]);
        }
    }
    int maxn=-(2<<30-1);
    for(int i=1;i<=n;i++) maxn=max(maxn,dis2[i]-dis1[i]);
    cout<<maxn;
}
View Code

猜你喜欢

转载自www.cnblogs.com/si-rui-yang/p/9568558.html