L3-028 森森旅游 题解(最短路)

题目链接

题目思路

显然只要正向建边从(1)跑最短路,然后反向建边从(n)跑最短路

然后答案用(multiset)维护即可

注意要判断是否联通,不联通(cost[i]=INF)

代码

#include<bits/stdc++.h>
#define fi first
#define se second
#define debug printf("
 I am here
");
using namespace std;
typedef long long ll;
typedef pair<ll,int> pii;
const int maxn=1e6+5,inf=0x3f3f3f3f,mod=233;
const double eps=1e-6;
const ll INF=0x3f3f3f3f3f3f3f3f;
int n,m,q;
int a[maxn];
int head[maxn],cnt;
ll dis[maxn][3];
struct edge{
    int to,next,c,d;
}e[maxn<<2];
ll cost[maxn];
void add(int u,int v,int c,int d){
    e[++cnt]={v,head[u],c,d};
    head[u]=cnt;
}
void dij(int x,int id){
    for(int i=1;i<=n;i++){
        dis[i][id]=INF;
    }
    dis[x][id]=0;
    priority_queue<pii,vector<pii>,greater<pii> > que;
    que.push({0,x});
    while(!que.empty()){
        int pos=que.top().se;
        ll len=que.top().fi;
        que.pop();
        if(len!=dis[pos][id]) continue;
        for(int i=head[pos];i;i=e[i].next){
            int to=e[i].to,w;
            if(id==1){
                w=e[i].c;
            }else{
                w=e[i].d;
            }
            if(dis[to][id]>dis[pos][id]+w){
                dis[to][id]=dis[pos][id]+w;
                que.push({dis[to][id],to});
            }
        }
    }
}
int u[maxn],v[maxn],c[maxn],d[maxn];
void init(){
    cnt=0;
    memset(head,0,sizeof(head));
    for(int i=1;i<=m;i++){
        add(v[i],u[i],c[i],d[i]);
    }
}
int main(){
    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=m;i++){
        scanf("%d%d%d%d",&u[i],&v[i],&c[i],&d[i]);
        add(u[i],v[i],c[i],d[i]);
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    dij(1,1);
    init();
    dij(n,2);
    multiset<ll> se;
    for(int i=1;i<=n;i++){
        cost[i]=dis[i][1]+(dis[i][2]+a[i]-1)/a[i];
        if(dis[i][1]==INF||dis[i][2]==INF){
            cost[i]=INF;
        }
        se.insert(cost[i]);
    }
    for(int i=1,x,y;i<=q;i++){
        scanf("%d%d",&x,&y);
        se.erase(se.lower_bound(cost[x]));
        cost[x]=dis[x][1]+(dis[x][2]+y-1)/y;
        if(dis[x][1]==INF||dis[x][2]==INF){
            cost[x]=INF;
        }
        se.insert(cost[x]);
        ll ans=*(se.begin());
        printf("%lld
",ans);
    }
    return 0;
}

卷也卷不过,躺又躺不平
原文地址:https://www.cnblogs.com/hunxuewangzi/p/14704403.html