题目描述:有一张图,共有n个节点,m条边,保证节点1到节点n有通路,找到一条路径上的两个节点(记为p,q——在该路径中,p在q之前),使p与q的权值之差最大;
蒟蒻思路:spfa求(p与q)的差值最大
在spfa的过程中,记每个队首元素为x,与其相连的节点记为y,则对于每个节点y,它的最优解(差值最大)只可能被两个量更新:
1.x的最优解;
2.节点y的权值-节点x的权值
辣鸡代码献上:
#include<bits/stdc++.h> using namespace std; struct Node{ int to,next; }e[2000005]; int pr[100005],cnt; int n,m; int head[500005],d[100005]; bool v[100005]; queue<int> q; void addedge(int x,int y) { e[++cnt].to=y; e[cnt].next=head[x]; head[x]=cnt; } void spfa() { memset(d,-1,sizeof(d)); q.push(1); v[1]=true; while(!q.empty()) { int x=q.front(); q.pop(); v[x]=false; for(int i=head[x];i;i=e[i].next) { int u=e[i].to,f=1; if(d[u]==-1||d[u]<pr[u]-pr[x]) { if(pr[u]-pr[x]>0)d[u]=pr[u]-pr[x]; f=0; } if(d[u]<d[x]) { d[u]=d[x]; f=0; } if(!f) { q.push(u); v[u]=true; } } } } int main() { scanf("%d %d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&pr[i]); for(int i=1;i<=m;i++) { int x,y,q; scanf("%d %d %d",&x,&y,&q); addedge(x,y); if(q==2)addedge(y,x); } spfa(); if(d[n]==-1)printf("0"); else printf("%d ",d[n]); return 0; }