• 【思维】迪杰斯特拉升维dp—— swerc Gym


    老套路了。。

    /*
    给定起点(xs,ys),
    终点(xd,yd),
    最大旅程距离B
    汽车的每公里代价C0
    其余交通方式数量T<=100 
    其余交通方式代价[C1..CT]<=100
    车站数量N<=1000
    第i个车站的位置(xi,yi),边数li<=100,每条边(j,mj)表示连向第j个车站,交通方式为mj 
    可以开车从s到任一车站或目的地,从任一车站开车到目的地,但是车站间不得开车
    问在旅程B内的最小代价 
    
    简化:无向图,起点s,终点t,边(u,v,a,b),要求s->t的路径边权b<=B条件下,边权a最小
    直接用二维dij算法,d[u][i]表示到点u,边权b=i情况下a的最小值 
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long 
    #define N 200005
    
    struct Edge{
        int to,nxt,a,b;
    }e[N<<1];
    int head[N],tot,s,t;
    void add(int u,int v,int b,int a){
        e[tot].to=v;e[tot].a=a;e[tot].b=b;e[tot].nxt=head[u];head[u]=tot++;
    }
    
    int sx,sy,dx,dy,x[N],y[N],B,c0,T,c[N],n;
    vector<pair<int,int> >G[N];
    int calc(int x1,int y1,int x2,int y2){
        return ceil(sqrt(1.0*(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
    }
    void build(){
        memset(head,-1,sizeof head);
        for(int i=1;i<=n;i++){
            for(auto p:G[i]){
                int id=p.first,m=p.second;
                int dis=calc(x[i],y[i],x[id],y[id]);
                add(i,id,dis,dis*c[m]);
                add(id,i,dis,dis*c[m]);        
            }
        }
        s=n+1,t=n+2;
        int dis=calc(sx,sy,dx,dy);
        add(s,t,dis,dis*c0);
        for(int i=1;i<=n;i++){
            dis=calc(sx,sy,x[i],y[i]);
            add(s,i,dis,dis*c0);
            dis=calc(dx,dy,x[i],y[i]);
            add(i,t,dis,dis*c0);
        }
    }
    
    
    struct Node{
        int a,b,id;
        bool operator>(const Node o) const {
            return a>o.a;
        }
    };
    int vis[1005][105],d[1005][105];
    priority_queue<Node,vector<Node>,greater<Node> >pq;
    void dij(){
        for(int i=1;i<=n+2;i++)
            for(int j=0;j<=B;j++)d[i][j]=1e9;
        memset(vis,0,sizeof vis);
        pq.push((Node){0,0,s});
        while(pq.size()){
            Node t=pq.top();pq.pop();
            if(vis[t.id][t.b])continue;
            vis[t.id][t.b]=1;
            int u=t.id,b=t.b,a=t.a;
            for(int i=head[u];i!=-1;i=e[i].nxt){
                int v=e[i].to;
                if(e[i].b+b<=B && !vis[v][e[i].b+b] && d[v][e[i].b+b]>a+e[i].a){
                    d[v][e[i].b+b]=a+e[i].a;
                    pq.push((Node){a+e[i].a,b+e[i].b,v});
                }
            }
        }
    }
    int main(){
        cin>>sx>>sy>>dx>>dy>>B>>c0>>T;
        for(int i=1;i<=T;i++)cin>>c[i];
        cin>>n;
        for(int i=1;i<=n;i++){
            scanf("%d%d",&x[i],&y[i]);
            int l;scanf("%d",&l);
            while(l--){
                int j,m;
                scanf("%d%d",&j,&m);
                G[i].push_back(make_pair(j+1,m));
            }
        }
        build();
        dij();
        int ans=1e9;
        for(int i=0;i<=B;i++)
            ans=min(ans,d[t][i]);
        if(ans>=1e9)cout<<-1<<'
    ';
        else cout<<ans<<'
    ';
    } 
  • 相关阅读:
    Vue(小案例_vue+axios仿手机app)_go实现退回上一个路由
    nyoj 635 Oh, my goddess
    nyoj 587 blockhouses
    nyoj 483 Nightmare
    nyoj 592 spiral grid
    nyoj 927 The partial sum problem
    nyoj 523 亡命逃窜
    nyoj 929 密码宝盒
    nyoj 999 师傅又被妖怪抓走了
    nyoj 293 Sticks
  • 原文地址:https://www.cnblogs.com/zsben991126/p/13122356.html
Copyright © 2020-2023  润新知