zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
    卷也卷不过,躺又躺不平
  • 相关阅读:
    Redis指令(2) ------String
    Redis指令(1) ------常用指令
    Redis数据类型
    Python set集合
    Python random 模块
    Python random 模块
    Python time 模块
    Python sys模块
    Python 递归函数
    Python 局部变量和全局变量
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/14704403.html
Copyright © 2011-2022 走看看