T1:Cqoi2009 最优贸易
题意就是让你在从1到n的路径上把商品以最低价格买入后以最高价格卖出。
大众解法就是把图正反各建一遍,然后从起点和终点分别跑一次spfa,计算 从起点到每个点的最小值 和 从每个点到终点的最大值。最后的答案就是每个点上存的最大值减最小值 的最大值。
1 #include<bits/stdc++.h> 2 #define N 100001 3 #define M 500001 4 using namespace std; 5 inline int read(){ 6 int x=0; bool f=1; char c=getchar(); 7 for(;!isdigit(c);c=getchar()) if(c=='-') f=0; 8 for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0'; 9 if(f) return x; 10 return 0-x; 11 } 12 int n,m,cost[N]; 13 14 struct edge{ 15 int v,next; 16 }e[M<<1],re[M<<1]; 17 int head[N],cnt; 18 inline void add(int u,int v){ 19 e[++cnt].v=v, e[cnt].next=head[u], head[u]=cnt; 20 } 21 22 int rev_head[N],rev_cnt; 23 inline void rev_add(int u,int v){ 24 re[++rev_cnt].v=v, re[rev_cnt].next=rev_head[u], rev_head[u]=rev_cnt; 25 } 26 27 int dis[2][N]; 28 bool vis[N],inque[N]; 29 30 void spfa(){ 31 queue<int>Q; 32 dis[0][1]=cost[1]; 33 Q.push(1); 34 35 int u,i; 36 while(!Q.empty()){ 37 u=Q.front(), Q.pop(), inque[u]=0; 38 for(i=head[u];i;i=e[i].next){ 39 if(!vis[e[i].v]){ 40 vis[e[i].v]=1; 41 dis[0][e[i].v]=cost[e[i].v]; 42 if(!inque[e[i].v]) {Q.push(e[i].v); inque[e[i].v]=1;} 43 } 44 if(dis[0][e[i].v]>dis[0][u]){ 45 dis[0][e[i].v]=dis[0][u]; 46 if(!inque[e[i].v]) {Q.push(e[i].v); inque[e[i].v]=1;} 47 } 48 } 49 } 50 } 51 52 void rev_spfa(){ 53 queue<int>Q; 54 memset(vis,0,sizeof vis); 55 dis[1][n]=cost[n]; 56 Q.push(n); 57 58 int u,i; 59 while(!Q.empty()){ 60 u=Q.front(), Q.pop(), inque[u]=0; 61 for(i=rev_head[u];i;i=re[i].next){ 62 if(!vis[re[i].v]){ 63 vis[re[i].v]=1; 64 dis[1][re[i].v]=cost[re[i].v]; 65 if(!inque[re[i].v]) {Q.push(re[i].v); inque[re[i].v]=1;} 66 } 67 if(dis[1][re[i].v]<dis[1][u]){ 68 dis[1][re[i].v]=dis[1][u]; 69 if(!inque[re[i].v]) {Q.push(re[i].v); inque[re[i].v]=1;} 70 } 71 } 72 } 73 } 74 75 int main(){ 76 n=read(),m=read(); 77 int i,x,y,z; 78 for(i=1;i<=n;i++) cost[i]=read(); 79 for(i=1;i<=m;i++){ 80 x=read(),y=read(),z=read(); 81 add(x,y); 82 if(z==2) add(y,x); 83 rev_add(y,x); 84 if(z==2) rev_add(x,y); 85 } 86 spfa(); 87 rev_spfa(); 88 int ans=0; 89 for(i=1;i<=n;i++) ans = max(ans, dis[1][i]-dis[0][i]); 90 printf("%d\n", ans>0 ? ans : 0); 91 return 0; 92 }