zoukankan      html  css  js  c++  java
  • AtCoder Beginner Contest 164E

    https://atcoder.jp/contests/abc164/tasks/abc164_e

    题意大概是有n个城市,m条无向边,初始状态下,位于1号城市,且初始有s个银币。从u点到v点需要花费a银币、b时间。在每个点可以花d时间去兑换c个银币,求从起点1到各个点需要的最短时间。

    思路:很显然这是一个单源最短路问题,我设计数组dis[i][j]表示,到达i城市还剩下j银币的最短时间。由于n的范围是2~50,且a的范围是1~50,那么从1号城市出发最多花费2500银币即可到达任意城市,那么初始的dis数组j维度最大就是2500.

           然后去跑一个普通的dij最短路,队列中存储的状态是{城市i,当前剩下的银币}。

           对于可以到达的城市,有转移状态 dis[y][w - b] = dis[cur][w] + dis(cur,v) (其中w是当前位于cur城市所剩下的银币,b为转移到y城市的银币花费数,那么转移到y城市就是w-b了)

           对于每一个可以到达的城市,也可以选择取钱,d[cur][min(w + c[cur],(ll)2500)] = d[cur][w] + t[cur],t数组为取钱的花费时间。对于每一个城市和当前在这个城市所剩下的银币数,这种状态也需要压入队列中去,然后去转移,整体来讲很像dp的思想。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn = 55;
     5 int n,m,tot;
     6 ll dis[maxn][2600],c[maxn],t[maxn];
     7 ll s;
     8 int head[maxn];
     9 struct node
    10 {
    11     int to,next;
    12     ll w,cost;
    13 }e[maxn*maxn];
    14 void add(int u,int v,ll w,ll c){
    15     e[tot].to = v;
    16     e[tot].w = w;
    17     e[tot].cost = c;
    18     e[tot].next = head[u];
    19     head[u] = tot++;
    20 }
    21 void dijkstra(ll s,ll d[][2600]){
    22     queue<pair<int,ll> > q;
    23     int vis[n+5][2600];
    24     for(int i = 1;i<=n;i++){
    25         for(int j = 0;j<=2500;j++) dis[i][j] = 0x3f3f3f3f3f3f3f3f,vis[i][j] = 0;
    26     }
    27     d[1][s] = 0;
    28     q.push({1,s});
    29     while(!q.empty()){
    30         int cur = q.front().first;
    31         ll w = q.front().second;
    32         q.pop();
    33         //if(vis[cur][w]) continue;
    34         //vis[cur][w] = 1;
    35         for(int i = head[cur];~i;i = e[i].next){
    36             int y = e[i].to;
    37             ll a = e[i].w,b = e[i].cost;
    38             if(w>=b && d[y][w - b] > d[cur][w] + a ){
    39                 d[y][w-b] = d[cur][w] + a;
    40                 q.push({y,w-b});
    41             }
    42         }
    43         if(d[cur][min(w + c[cur],(ll)2500)]> d[cur][w] + t[cur]){
    44             d[cur][min(w + c[cur],(ll)2500)] = d[cur][w] + t[cur];
    45             q.push({cur,min(w + c[cur],(ll)2500)});
    46         }
    47     }
    48 }
    49 int main(){
    50     scanf("%d%d%lld",&n,&m,&s);
    51     s = min(s,(ll)2500);
    52     for (int i = 0; i <=n; ++i) head[i] = -1;
    53         /* code */
    54     for (int i = 0; i <m; ++i)
    55     {
    56         int u,v;ll a,b;
    57         scanf("%d%d%lld%lld",&u,&v,&a,&b);
    58         add(u,v,b,a);
    59         add(v,u,b,a);
    60         /* code */
    61     }
    62     for(int i = 1;i<=n;i++){
    63         scanf("%lld%lld",&c[i],&t[i]);
    64     }
    65     dijkstra(s,dis);
    66     for(int i = 2;i<=n;i++){
    67         ll ans = 0x3f3f3f3f3f3f3f3f;
    68         for(int j = 0;j<=2500;j++) ans = min(ans,dis[i][j]);
    69         printf("%lld
    ",ans);
    70     }
    71     return 0;
    72 }
  • 相关阅读:
    Selenium中的几种等待方式,需特别注意implicitlyWait的用法
    在chrome下的文本框sendkeys,提示element can't focus--解决方法
    selenium 切换窗口 每次成功code
    xpath实例 --//span[contains(.,'资讯管理')]
    SQL 常用语句
    TestNG教程
    ant常用命令
    win server服务安装
    又一次受启发
    firefox安装firebugXPath Checker
  • 原文地址:https://www.cnblogs.com/AaronChang/p/12813293.html
Copyright © 2011-2022 走看看