l3-1 因为每一次只能换一次钱,所以建一个正图,一个反图,正图按原来的钱判断第一个点到其他点要花的最少的现金,也就是求一次最短路,反图按照旅游金求所有点到终点的最短路,查询的时候记录下每个点到终点要多少现金和起点到这个点需要多少现金,每次都取最少的点就可以,不过写的时候挺麻烦的,有很多坑;
#include<bits/stdc++.h> using namespace std; #define LL long long #define pb push_back struct mp { LL fm,to,w1,w2; mp(LL a,LL b,LL c,LL d) { fm=a,to=b,w1=c,w2=d; } }; vector<mp>p[200005]; vector<mp>p1[200005]; struct mmp { LL id,w; mmp(LL a,LL b) { id=a;w=b; } bool operator<(const mmp p1)const { return w>p1.w; } }; LL n,m,k; priority_queue<mmp>q; priority_queue<mmp>q1; LL vis[200005],dis[200005]; LL vis1[200005],dis1[200005]; LL real[200005]; void djs() { for(int i=0;i<200005;i++)vis[i]=vis1[i]=0,dis[i]=dis1[i]=1e18+7; q.push(mmp(1,0)); dis[1]=0; q1.push(mmp(n,0)); dis1[n]=0; while(!q.empty()) { mmp o=q.top(); q.pop();//cout<<o.id<<endl; if(vis[o.id]==1)continue; vis[o.id]=1; for(int i=0;i<p1[o.id].size();i++) { if(vis[p1[o.id][i].to]==1)continue; if(dis[o.id]+p1[o.id][i].w1<dis[p1[o.id][i].to]) { dis[p1[o.id][i].to]=dis[o.id]+p1[o.id][i].w1; q.push(mmp(p1[o.id][i].to,dis[p1[o.id][i].to])); } } } while(!q1.empty()) { mmp o=q1.top(); q1.pop();//cout<<o.id<<endl; if(vis1[o.id]==1)continue; vis1[o.id]=1; for(int i=0;i<p[o.id].size();i++) { if(vis1[p[o.id][i].to]==1)continue; if(dis1[o.id]+p[o.id][i].w2<dis1[p[o.id][i].to]) { dis1[p[o.id][i].to]=dis1[o.id]+p[o.id][i].w2; q1.push(mmp(p[o.id][i].to,dis1[p[o.id][i].to])); } //cout<<q1.size()<<endl; } } } int y[200005]; map<LL,LL>ss; map<LL,LL>ee; set<LL>rr; int main() { cin>>n>>m>>k; while(m--) { int a,b; LL c,d; scanf("%d%d%lld%lld",&a,&b,&c,&d); p[b].pb(mp(b,a,c,d)); p1[a].pb(mp(a,b,c,d)); } djs(); for(int i=1;i<=n;i++)cin>>y[i]; LL ans=dis[n]; for(int i=1;i<=n;i++) { //cout<<i<<" "<<dis[i]<<" "<<dis1[i]<<endl; if(dis[i]==1e18+7||dis1[i]==1e18+7)continue; LL num=dis[i]+(dis1[i]+y[i]-1)/y[i]; //if(ans>num)ans=num; ss[i]=num; rr.insert(num); //cout<<" "<<num<<endl; ee[num]++; } while(k--) { int a,b; scanf("%d%d",&a,&b); if(dis[a]==1e18+7||dis1[a]==1e18+7) { printf("%lld\n",*rr.begin()); continue; } LL num=dis[a]; num+=(dis1[a]+b-1)/b; //cout<<" "<<num<<endl; ee[ss[a]]--; ee[num]++; //cout<<ss[a]<<" "<<ee[ss[a]]<<endl; if(ee[ss[a]]==0)rr.erase(ss[a]); ss[a]=num; rr.insert(num); printf("%lld\n",*rr.begin()); } }