• 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018) D. Delivery Delays (二分+最短路+DP)


    题目链接:https://codeforc.es/gym/101933/problem/D

    题意:地图上有 n 个位置和 m 条边,每条边连接 u、v 且有一个距离 w,一共有 k 个询问,每个询问表示 ti 时间在位置 ui 有人下单点了披萨,而披萨店在 di 时间做好披萨可以送出去,披萨店在位置 1,送披萨必须按顺序送,问客人从下单到拿到披萨的最长等待时间最短是多少。

    题解:首先可以对每个点跑一次 dij,预处理出每两点之间的最短路,然后考虑二分答案,判断是否合法。dp[i][j]代表已经送完前 i 个位置,且拿了前 j 个位置的披萨的最小时间,还需要一维 k,0 表示送完以后当前在第 i 个点披萨的位置,1 表示当前在披萨店,然后进行转移即可。

      1 #include <bits/stdc++.h>
      2 #define sd(a) scanf("%d",&a)
      3 #define mst(a,b) memset(a,b,sizeof a)
      4 #define mp make_pair
      5 typedef long long ll;
      6 #define pb push_back
      7 using namespace std;
      8 typedef pair<int, int> pii;
      9 const int maxn = 2e5 + 10;
     10 //int inf = 0x3f3f3f3f;
     11 const int mod = 1000000007;
     12 ll dis[1111][1111];
     13 vector<pii>g[1111];
     14 bool vis[1111];
     15 void dij(int s, int n) {
     16     ll inf2 = 1e16;
     17     for(int i = 1; i <= n; ++i)
     18         dis[s][i] = inf2, vis[i] = 0;
     19     dis[s][s] = 0;
     20     priority_queue<pair<ll, int> >q;
     21     q.push(mp(0, s));
     22     for(; !q.empty();) {
     23         int u = q.top().second;
     24         q.pop();
     25         if(vis[u])
     26             continue;
     27         vis[u] = 1;
     28         for(int j = 0, sz = g[u].size(); j < sz; ++j) {
     29             int v = g[u][j].first;
     30             int w = g[u][j].second;
     31             if(dis[s][v] > dis[s][u] + w) {
     32                 dis[s][v] = dis[s][u] + w;
     33                 q.push(mp(-dis[s][v], v));
     34             }
     35         }
     36     }
     37 }
     38 int s[1111], to[1111], t[1111];
     39 ll dp[1111][1111][2];
     40 bool check(ll x, int n, int k) {
     41     ll inf2 = 1e16;
     42     for(int i = 0; i <= k; ++i)
     43         for(int j = 0; j <= k; ++j)
     44             dp[i][j][0] = dp[i][j][1] = inf2;
     45     dp[0][0][1] = 0;
     46     for(int i = 0; i < k; ++i) {
     47         for(int j = i; j <= k; ++j) {
     48             for(int o = 0; o < 2; ++o) {
     49                 if(dp[i][j][o] == inf2)
     50                     continue;
     51                 if(!o) {
     52                     dp[i][j][1] = min(dp[i][j][1], dp[i][j][0] + dis[to[i]][1]);
     53                     if(j > i && i < k) {
     54                         ll time = dp[i][j][0] + dis[to[i]][to[i + 1]];
     55                         if(s[i + 1] + x >= time)
     56                             dp[i + 1][j][0] = min(dp[i + 1][j][0], time);
     57                     }
     58                 } else {
     59                     if(j < k)
     60                         dp[i][j + 1][1] = min(dp[i][j + 1][1], max(dp[i][j][1], (ll)t[j + 1]) );
     61                     if(i < k && j >= i + 1) {
     62                         ll time = dp[i][j][1] + dis[1][to[i + 1]];
     63                         if(s[i + 1] + x >= time)
     64                             dp[i + 1][j][0] = min(dp[i + 1][j][0], time);
     65                     }
     66                 }
     67             }
     68         }
     69     }
     70     return dp[k][k][0] != inf2;
     71 }
     72 
     73 int main() {
     74 #ifdef local
     75     freopen("in", "r", stdin);
     76 #endif // local
     77     int n, m;
     78     sd(n), sd(m);
     79     for(int i = 1; i <= m; ++i) {
     80         int u, v, w;
     81         sd(u), sd(v), sd(w);
     82         g[u].pb(mp(v, w));
     83         g[v].pb(mp(u, w));
     84     }
     85     int k;
     86     sd(k);
     87     to[0] = 1;
     88     for(int i = 1; i <= k; ++i)
     89         sd(s[i]), sd(to[i]), sd(t[i]);
     90     for(int i = 1; i <= n; ++i)
     91         dij(i, n);
     92     ll ans = 1e16;
     93     ll l = 0, r = ans;
     94     for(; l <= r;) {
     95         ll mid = (l + r) >> 1;
     96         if(check(mid, n, k))
     97             ans = mid, r = mid - 1;
     98         else
     99             l = mid + 1;
    100     }
    101     printf("%lld
    ", ans);
    102     return 0;
    103 }
  • 相关阅读:
    MSCRM2011 在Form里创建一个密码栏
    MSCRM 2011 可视化Ribbon编辑工具,超级强大!
    C# List去重
    理解Dynamic CRM2011 Ribbon里Sequence 和TemplateAlias意思
    SQL 语法大全
    SQL语句case关键字的用法
    ASP.NET 导出Excel时,某单元格内一部分文字加粗加下划线
    ASP.NET 导出Excel时,出现CLSID {0002450000000000C000000000000046} ,拒绝访问。
    通过DOM节点操作来获取表单信息
    嗨,博客园
  • 原文地址:https://www.cnblogs.com/scaulok/p/9900095.html
Copyright © 2020-2023  润新知