/*
解题思路:
森森从1到达n,可能会在中途点t(也可以是1或者n)换取旅游金 ;
如果在t点换完以后,那么后面的旅途只能用旅游金,那么我们可以在
1—t用最少现金(第一个迪杰斯特拉),t-n用最少旅游金(第二个)
所以正向建一个最短路径得到1到t的最小权,反向建一个得到t到n的最小权;
这里的迪杰斯特拉要用优先队列来进行迪杰斯特拉,因为题目说 点a到b可能不止一条路!
两个最小路径建完以后,把1——n上的所有点都作为换取旅行金的点,进行计算总花费金额
把每个点作为换取点后,所需总金额放进一个multiset容器(看完代码你会知道为什么是multiset)
再每一次更新汇率后,也更新multiset里面的值。
*/
单源最短路径 Dijkstra+优先队列_Meloor的博客-CSDN博客
C++优先队列自定义排序总结_KRYON!的博客-CSDN博客_优先队列自定义排序
/*
解题思路:
森森从1到达n,可能会在中途点t(也可以是1或者n)换取旅游金 ;
如果在t点换完以后,那么后面的旅途只能用旅游金,那么我们可以在
1—t用最少现金(第一个迪杰斯特拉),t-n用最少旅游金(第二个)
所以正向建一个最短路径得到1到t的最小权,反向建一个得到t到n的最小权;
这里的迪杰斯特拉要用优先队列来进行迪杰斯特拉,因为题目说 点a到b可能不止一条路!
两个最小路径建完以后,把1——n上的所有点都作为换取旅行金的点,进行计算总花费金额
把每个点作为换取点后,所需总金额放进一个multiset容器(看完代码你会知道为什么是multiset)
再每一次更新汇率后,也更新multiset里面的值。
*/
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
const long long INF=1e18;
typedef pair<int,long long> P;//没用上
typedef long long LL;
struct node{
int id;
LL cost;
friend int operator <(const struct node &a,const struct node &b) //使得优先队列中cost最小的优先
{
return a.cost>b.cost;
}
};
vector<node> T1[maxn],T2[maxn];//存图
int n,m,o,a,b,vis1[maxn],vis2[maxn];//vis用于标记
LL w1,w2,huan[maxn],tran[maxn],D1[maxn],D2[maxn];//D用来存最短权值 ,tran存放可达点的总金额
void djs(int a,LL D[],vector<node> T[],int vis[])
{
priority_queue<node> que;
fill(D+1,D+n+1,INF);
D[a]=0;
que.push({a,0});
while(!que.empty())
{
int p=que.top().id;
que.pop();
if(vis[p]) continue;
vis[p]=1;
for(int i=0;i<T[p].size();i++)
{
int u=T[p][i].id;
LL w=T[p][i].cost;
if(D[u]>D[p]+w)
{
D[u]=D[p]+w;
que.push({u,D[u]});
}
}
}
}
int main(void)
{
scanf("%d%d%d",&n,&m,&o);
for(int i=0;i<m;i++)
{
scanf("%d%d%lld%lld",&a,&b,&w1,&w2);
T1[a].push_back({b,w1});//正向图
T2[b].push_back({a,w2});//反向图
}
for(int i=1;i<=n;i++)
{
scanf("%lld",&huan[i]);
}
djs(1,D1,T1,vis1);
djs(n,D2,T2,vis2);
multiset<LL> ma;
for(int i=1;i<=n;i++)
{
if(D1[i]==INF||D2[i]==INF) continue;//i点不可达
// (D2[i]+huan[i]-1)/huan[i]) 的意思如下
//如果汇率是8,t-n花费的旅游金是39,那么39/8=4,但是4*8=32,那就不对了,花费的钱应该是5;
ma.insert(tran[i]=D1[i]+(D2[i]+huan[i]-1)/huan[i]);//tran[i]存放可达点的总金额
}
while(o--)
{
int xi;
LL ai;
scanf("%d%lld",&xi,&ai);
if(!tran[xi]||huan[xi]==ai)//如果xi点不可达或者xi点的汇率和之前一样
{
printf("%lld\n",*ma.begin());
}
else
{
ma.erase(ma.find(tran[xi]));
huan[xi]=ai;
ma.insert(tran[xi]=D1[xi]+(D2[xi]+huan[xi]-1)/huan[xi]);
printf("%lld\n",*ma.begin());
}
}
return 0;
}