P1073 最优贸易
最短路
(分号逗号傻傻分不清???)
我们从起点开始沿着正向边跑一遍dijkstra,求出从起点到某个点所经过的城市中水晶球售价最小是多少
我们从终点开始沿着反向边跑一遍dijkstra,求出从终点到某个点所经过的城市中水晶球售价最大是多少
然后对于每个点,枚举找到差价最大的。
end.
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<cctype> using namespace std; template <typename T> inline T min(T &a,T &b) {return a<b ?a:b;} template <typename T> inline T max(T &a,T &b) {return a>b ?a:b;} template <typename T> inline void read(T &x){ char c=getchar(); x=0; while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar(); } struct data{ int d,u; bool operator < (const data &tmp) const {return d>tmp.d;} }; int n,m,ans,d[2][100002],val[100002]; int cnt[2],hd[2][100002],nxt[2][1000002],ed[2][100002],poi[2][1000002]; inline void add(int x,int y,int p){ nxt[p][ed[p][x]]=++cnt[p]; hd[p][x]= hd[p][x] ? hd[p][x]:cnt[p]; ed[p][x]=cnt[p]; poi[p][cnt[p]]=y; } void dijkstra_s(int p){ //从起点开始第一遍跑,找最小值 memset(d[p],127,sizeof(d[p])); priority_queue <data> h; h.push((data){d[p][1]=val[1],1}); while(!h.empty()){ data x=h.top(); h.pop(); if(x.d!=d[p][x.u]) continue; for(int i=hd[p][x.u];i;i=nxt[p][i]) if(x.d<d[p][poi[p][i]]){ d[p][poi[p][i]]=min(x.d,val[poi[p][i]]); h.push((data){d[p][poi[p][i]],poi[p][i]}); } } } void dijkstra_t(int p){ //从终点开始第二遍跑,找最大值 memset(d[p],-1,sizeof(d[p])); priority_queue <data> h; h.push((data){d[p][n]=val[n],n}); while(!h.empty()){ data x=h.top(); h.pop(); if(x.d!=d[p][x.u]) continue; for(int i=hd[p][x.u];i;i=nxt[p][i]) if(x.d>d[p][poi[p][i]]){ d[p][poi[p][i]]=max(x.d,val[poi[p][i]]); h.push((data){d[p][poi[p][i]],poi[p][i]}); } } } int main(){ read(n); read(m); int q1,q2,q3; for(int i=1;i<=n;++i) read(val[i]); for(int i=1;i<=m;++i){ read(q1); read(q2); read(q3); add(q1,q2,0); add(q2,q1,1); //正/反向边建两个图 if(q3==2) add(q2,q1,0),add(q1,q2,1); //不用括号再不用逗号就GG了QAQ } dijkstra_s(0); dijkstra_t(1); for(int i=1;i<=n;++i) ans=max(ans,d[1][i]-d[0][i]); //找差值最大 printf("%d",ans); return 0; }