【NOIP2009】最优贸易

有关于最短路的题目。

我们先将将读入的原图存储下来,在存储一张原图的反向图,之后再进行一些操作。

我们在原图上求出一个数组d,其中d[i]表示从起点到i经过的点权最小的值,同理,我们在反向图上求出一个数组f,表示从终点到i经过的点权最大的值,这样一来,答案便是max(f[i]-d[i]).

我们在原图和反向图中各跑一遍迪杰斯特拉即可。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <queue>
 6 using namespace std;
 7 inline int read() {
 8     int ret=0;
 9     int op=1;
10     char c=getchar();
11     while(c<'0'||c>'9') {if(c=='-') op=-1; c=getchar();}
12     while(c<='9'&&c>='0') ret=ret*10+c-'0',c=getchar();
13     return ret*op;
14 }
15 typedef pair<int,int> pii;
16 int n,m;
17 struct node {
18     int next,to;
19 }a1[500010<<1],a2[500010<<1];
20 int head1[500010<<1],head2[500010<<1],num1,num2;
21 int val[100010];
22 int f[100010],d[100010],ans,vis[100010];
23 inline void add(int from,int to) {
24     a1[++num1].next=head1[from]; a1[num1].to=to; head1[from]=num1;
25     swap(from,to);
26     a2[++num2].next=head2[from]; a2[num2].to=to; head2[from]=num2;
27 }
28 int main() {
29     n=read(); m=read();
30     for(int i=1;i<=n;i++) val[i]=read();
31     for(int i=1;i<=m;i++) {
32         int x=read(),y=read(),z=read();
33         if(z==1) {
34             add(x,y);
35         }
36         else {
37             add(x,y);
38             add(y,x);
39         }
40     }
41     memset(d,0x3f,sizeof(d));
42     memset(vis,0,sizeof(vis));
43     priority_queue<pii,vector<pii>,greater<pii> >q;
44     d[1]=val[1];
45     q.push(make_pair(val[1],1));
46     while(!q.empty()) {
47         int now=q.top().second;
48         q.pop();
49         if(vis[now]) continue ;
50         vis[now]=1;
51         for(int i=head1[now];i;i=a1[i].next) {
52             int v=a1[i].to;
53             d[v]=min(d[now],val[v]);
54             q.push(make_pair(d[v],v));
55         }
56     }
57     memset(f,0xcf,sizeof(f));
58     memset(vis,0,sizeof(vis));
59     while(!q.empty()) q.pop();
60     f[n]=val[n];
61     q.push(make_pair(val[n],n));
62     while(!q.empty()) {
63         int now=q.top().second;
64         q.pop();
65         if(vis[now]) continue ;
66         vis[now]=1;
67         for(int i=head2[now];i;i=a2[i].next) {
68             int v=a2[i].to;
69             f[v]=max(f[now],val[v]);
70             q.push(make_pair(f[v],v));
71         }
72     }
73     ans=-1;
74     for(int i=1;i<=n;i++)
75         ans=max(ans,f[i]-d[i]);
76     printf("%d
",ans);
77     return 0;
78 }
AC Code
原文地址:https://www.cnblogs.com/shl-blog/p/10774503.html