题目
求两个点,可以与起点和终点连通,权值差最大。
分析
那么同时维护最小值和最大值,找到最合适的中间点
代码
#include <cstdio>
using namespace std;
struct q{int x,y,next;}e[500001]; bool v[100001];
int n,m,c,low[100001],cost[100001],max[100001],ls[100001];
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%d",&cost[i]),low[i]=cost[i];//一开始最小为原花费
for (int i=1;i<=m;i++){
int u,v,z;
scanf("%d%d%d",&u,&v,&z);
e[++c].x=u; e[c].y=v; e[c].next=ls[u]; ls[u]=c;//单向
if(z==2)e[++c].x=v,e[c].y=u,e[c].next=ls[v],ls[v]=c;//双向
}
int head=0,tail=1,t,list[150001]; list[1]=1; v[1]=1;
do{
head++; //出队
if (head>150000) break;
t=ls[list[head]];
while (t){
if (low[e[t].x]<=low[e[t].y]||max[e[t].x]>=max[e[t].y]){//松弛
if (low[e[t].x]<=low[e[t].y]) low[e[t].y]=low[e[t].x];//寻找最小的值。
if (max[e[t].x]>max[e[t].y]) max[e[t].y]=max[e[t].x];//寻找最大的值
if (cost[e[t].y]-low[e[t].y]>max[e[t].y]) max[e[t].y]=cost[e[t].y]-low[e[t].y];//如果可以从这个点卖掉并且比当前的值大就松弛操作
if (!v[e[t].y]){
v[e[t].y]=1;
tail++;
if (tail>150000) break;
list[tail]=e[t].y;//入队
}
}
t=e[t].next;
}
v[list[head]]=0;
}while (head<tail);
printf("%d",max[n]);
return 0;
}