L3-028
题意可知:从 1号城市 开始使用现金走到 k号城市 再从k号城市 开始使用旅游金走到 n号城市(1<=k<=n)
建立权值为c的正向边,求出从1跑到所有点的最短路
建立权值为d的反向边,求出从所有点跑到n的最短路
对于点k消耗的现金数量为 dis[1->k] + (dis[k->n]+a[k]-1)/a[k]
由于汇率a[i]会改变,所以可以使用线段树或者multiset去存储以1~n为转折点k时消耗的现金数量
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
#define int long long
typedef long long ll;
int n,m,k;
struct edge{
int y,c,d;
edge(int Y,int C,int D):y(Y),c(C),d(D){}
};
int inf;
vector<edge>z[100005],f[100005];
int zc[100005],fd[100005];
int res[100005];
bool vis[100005];
void bfs(){
memset(zc,127,sizeof zc);
memset(fd,127,sizeof fd);
inf=zc[0];
priority_queue<pair<int,int>>q;
zc[1]=0;
q.push({0,1});
while(q.size()){
int x=q.top().second;
q.pop();
if(vis[x])continue;
vis[x]=true;
for(auto [y,c,d]:z[x]){
if(zc[y]>zc[x]+c){
zc[y]=zc[x]+c;
q.push({-zc[y],y});
}
}
}
memset(vis,0,sizeof vis);
fd[n]=0;
q.push({0,n});
while(q.size()){
int x=q.top().second;
q.pop();
if(vis[x])continue;
vis[x]=true;
for(auto [y,c,d]:f[x]){
if(fd[y]>fd[x]+d){
fd[y]=fd[x]+d;
q.push({-fd[y],y});
}
}
}
}
void slove(){
cin>>n>>m>>k;
for(int i=1;i<=m;i++){
int u,v,c,d;
cin>>u>>v>>c>>d;
if(u==v)continue;
z[u].push_back(edge(v,c,d));
f[v].push_back(edge(u,c,d));
}
bfs();
multiset<int>s;
for(int i=1;i<=n;i++){
int x;
cin>>x;
if(fd[i]==inf)continue;
res[i]=(fd[i]+x-1)/x+zc[i];
s.insert(res[i]);
}
while(k--){
int i,x;
cin>>i>>x;
if(fd[i]!=inf){
s.erase(s.find(res[i]));
res[i]=(fd[i]+x-1)/x+zc[i];
s.insert(res[i]);
}
cout<<min(zc[n],*s.begin())<<endl;
}
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int T=1;
// cin>>T;
while(T--){
slove();
}
return 0;
}
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
#define int long long
#define mid ((l+r)>>1)
#define lt now<<1
#define rt now<<1|1
#define ltr lt,l,mid
#define rtr rt,mid+1,r
typedef long long ll;
int n,m,k;
struct edge{
int y,c,d;
edge(int Y,int C,int D):y(Y),c(C),d(D){}
};
int inf;
vector<edge>z[100005],f[100005];
int zc[100005],fd[100005];
int res[100005];
int tr[400005];
bool vis[100005];
void bfs(){
memset(zc,127,sizeof zc);
memset(fd,127,sizeof fd);
inf=zc[0];
priority_queue<pair<int,int>>q;
zc[1]=0;
q.push({0,1});
while(q.size()){
int x=q.top().second;
q.pop();
if(vis[x])continue;
vis[x]=true;
for(auto [y,c,d]:z[x]){
if(zc[y]>zc[x]+c){
zc[y]=zc[x]+c;
q.push({-zc[y],y});
}
}
}
memset(vis,0,sizeof vis);
fd[n]=0;
q.push({0,n});
while(q.size()){
int x=q.top().second;
q.pop();
if(vis[x])continue;
vis[x]=true;
for(auto [y,c,d]:f[x]){
if(fd[y]>fd[x]+d){
fd[y]=fd[x]+d;
q.push({-fd[y],y});
}
}
}
}
void build(int now,int l,int r){
if(l==r){
tr[now]=res[l];
return ;
}
build(ltr);
build(rtr);
tr[now]=min(tr[lt],tr[rt]);
}
void upd(int now,int l,int r,int i,int x){
if(i==l&&i==r){
tr[now]=x;
return ;
}
if(i<=mid)upd(ltr,i,x);
else upd(rtr,i,x);
tr[now]=min(tr[lt],tr[rt]);
}
void slove(){
cin>>n>>m>>k;
for(int i=1;i<=m;i++){
int u,v,c,d;
cin>>u>>v>>c>>d;
if(u==v)continue;
z[u].push_back(edge(v,c,d));
f[v].push_back(edge(u,c,d));
}
bfs();
for(int i=1;i<=n;i++){
int x;
cin>>x;
if(fd[i]!=inf)res[i]=(fd[i]+x-1)/x+zc[i];
else res[i]=inf;
}
build(1,1,n);
while(k--){
int i,x;
cin>>i>>x;
if(fd[i]!=inf){
res[i]=(fd[i]+x-1)/x+zc[i];
upd(1,1,n,i,res[i]);
}
cout<<min(zc[n],tr[1])<<endl;
}
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int T=1;
// cin>>T;
while(T--){
slove();
}
return 0;
}
L3-029
虽然N很大但是M很小并且题目保证有唯一解,所以可以使用暴力dfs
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
typedef long long ll;
int n,m;
vector<int>ans,h,a[105];
bool vis[105];
void dfs(int now){
if(ans.size()==m){
bool t=false;
for(auto x:ans){
if(t)cout<<" ";
else t=true;
cout<<x;
}
exit(0);
}
for(int i=0;i<m;i++){
if(vis[i])continue;
int j=0;
for(auto x:a[i]){
if(x!=h[now+j])break;
j++;
}
if(j<a[i].size())continue;
ans.push_back(i+1);
vis[i]=true;
dfs(now+a[i].size()-1);
vis[i]=false;
ans.pop_back();
}
}
void slove(){
cin>>n;
h.assign(n,0);
for(auto &x:h)cin>>x;
cin>>m;
for(int i=0;i<m;i++){
int k;
cin>>k;
a[i].assign(k,0);
for(auto &x:a[i])cin>>x;
}
dfs(0);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int T=1;
// cin>>T;
while(T--){
slove();
}
return 0;
}