1 /*
2 思路:
3 利用最短路的变形
4 分别从起点搜一次
5 从终点搜一次
6 从起点搜出从起点到达各点的最小值
7 从终点搜出从终点到达各点的最大值(所有可以到达的点)
8
9 主要思想是:
10 从 1 到 i 再从 i 到 n
11 从 1 到 i 时 路径是正着存的
12
13 从i 到 n 时我们把路径反着存一次
14 变成求 从 n 到 i 了(此处最重要)
15 */
16 #include<iostream>
17 #include<cstdio>
18 #include<cstring>
19 #include<queue>
20 #define qmax(a,b) ((a)>(b))?(a):(b)
21 #define qmin(a,b) ((a)<(b))?(a):(b)
22 using namespace std;
23
24 const int roadnum=500001;
25 const int citynum=100001;
26 struct node
27 {
28 int e;
29 int next;
30 }edge[roadnum*2];
31
32 int k1[citynum],k2[citynum];
33 bool flag1[citynum],flag2[citynum];
34 int maxval[citynum],minval[citynum];
35 int n,m;
36 int k=0;
37 queue <int> q;
38
39 void ADD(int from,int to)
40 {
41 edge[k].e=to;
42 edge[k].next=k1[from];
43 k1[from]=k++;
44
45 edge[k].e=from;
46 edge[k].next=k2[to];
47 k2[to]=k++;
48 }
49
50 void init()
51 {
52 int i,x,y,z;
53 memset(flag1,0,sizeof(flag1));
54 memset(flag2,0,sizeof(flag2));
55 memset(k1,-1,sizeof(k1));//从起点搜索用
56 memset(k2,-1,sizeof(k2));//从终点搜索用
57 for(i=1;i<=n;++i)
58 {
59 scanf("%d",&minval[i]);
60 maxval[i]=minval[i];
61 }
62 while(m--)
63 {
64 scanf("%d%d%d",&x,&y,&z);
65 ADD(x,y);
66 if(2==z)ADD(y,x);
67 }
68 }
69
70 int spfa()
71 {
72 int x,y,i;
73 while(!q.empty())q.pop();
74 q.push(1);
75 flag1[1]=1;
76 while(!q.empty())// 这个while() 控制从 从起点 可以到达的所有点可以取的最小值
77 {
78 x = q.front();
79 q.pop();
80 for(i=k1[x];i!=-1;i=edge[i].next)
81 {
82 y= edge[i].e;
83 minval[y]=qmin(minval[x],minval[y]);
84 if(!flag1[y])
85 {
86 q.push(y);
87 flag1[y]=1;
88 }
89 }
90 }
91
92 q.push(n);
93 flag2[n]=1;
94 while(!q.empty())// 因为路径反着存了一次 我们从终点 逆向搜回去 可以到达各点的最大值
95 { //相当于从各点走到终点的最大值(因为路径反存了一次)
96 x = q.front();
97 q.pop();
98 for(i=k2[x];i!=-1;i=edge[i].next)
99 {
100 y = edge[i].e;
101 maxval[y]=qmax(maxval[x],maxval[y]);
102 if(!flag2[y])
103 {
104 q.push(y);
105 flag2[y]=1;
106 }
107 }
108 }
109 int te=0;
110 for(i=1;i<=n;++i)
111 if(flag1[i] && flag2[i] && maxval[i]-minval[i]>te)// flag1[i]!=0表明从起点可以到这个点
112 te=maxval[i]-minval[i]; //flag2[i]!=0表明从点 i 可以到达终点
113 return te;
114 }
115
116 int main()
117 {
118 while(EOF != scanf("%d%d",&n,&m))
119 {
120 init();
121 printf("%d\n",spfa());
122 }
123 return 0;
124 }