[CodeForces gym 101630 J] 过路费(最短路)

problem

给定一张图 n n n 个点 m m m 条边,并给定阈值 k k k,以及起终点 s , t s,t s,t

然后每条边经过都需要支付 w w w 的花费,形如 ( u , v , w ) (u,v,w) (u,v,w) 格式给出。

s → t s\rightarrow t st 的最小花费。

最小花费定义如下:

  • 如果该路径经过的边数 ≤ k \le k k,则就是该路径的边权和。
  • 如果该路径经过的边数 > k >k >k,则只需要求前 k k k 大的边权和。

n , k ≤ 1000 , m ≤ 2000 , 1 ≤ w i ≤ 1 e 9 n,k\le 1000,m\le 2000,1\le w_i\le 1e9 n,k1000,m2000,1wi1e9

原题:CF Gym 101630 J

solution

考试设计的部分分实际上能让纯暴力搜路径做法拿到 70 的高分?!!(○´・д・)ノ

我们直接枚举第 k k k 大的边权 x x x,然后把所有边权全都减去 x x x,当然需要和 0 0 0 max \text{max} max

然后求 s → t s\rightarrow t st 的最短路 + x ∗ k +x*k +xk 就是最短路的真正花费,再全局取最小值即可。

这样子做,我们可以求出所有第 k k k 大边权是 x x x 的所有路径。

如果这条路径不足 k k k,那么你让 k k k 大边权为 0 0 0 就行了。

接下来我们要证明此时所有第 k k k 大边权 ≠ x \neq x =x 的路径花费都不存在算得比真实花费小的情况。

只要不影响到最终答案即可。

证明其实很简单。可能不太严谨??

  • k k k 大边权 < x <x <x

    那么前 k k k 大至少有一个减掉后边权成为 0 0 0,后面用 k ∗ x k*x kx 抵消这个减去的边权时,相当于多弥补了一些花费。

  • k k k 大边权 > x >x >x

    那么除去前 k k k 大,后面的某些边权可能也会 > x >x >x,减去后还是存在花费会被统计进路径中。

    而实际上后面这些边权都是不用算的。

那么这道题就变成了 O ( n 2 log ⁡ n ) O(n^2\log n) O(n2logn) 了。

code

#include <bits/stdc++.h>
using namespace std;
#define maxn 1005
#define int long long
#define Pair pair < int, int >
int n, m, k, s, t;
struct edge{ int u, v, w; }E[maxn << 1];
priority_queue < Pair, vector < Pair >, greater < Pair > >q;
int dis[maxn];
vector < pair < int, int > > G[maxn];

int dijkstra() {
    memset( dis, 0x3f, sizeof( dis ) );
    q.push( make_pair( dis[s] = 0, s ) );
    while( ! q.empty() ) {
        int u = q.top().second; int w = q.top().first; q.pop();
        if( dis[u] ^ w ) continue;
        for( int i = 0;i < G[u].size();i ++ ) {
            int v = G[u][i].first; w = G[u][i].second;
            if( dis[v] > dis[u] + w ) q.push( make_pair( dis[v] = dis[u] + w, v ) );
        }
    }
    return dis[t];
}

int solve( int x ) {
    for( int i = 1;i <= n;i ++ ) G[i].clear();
    for( int i = 1;i <= m;i ++ ) G[E[i].u].push_back( make_pair( E[i].v, max( 0ll, E[i].w - x ) ) );   
    return dijkstra() + x * k;
}

signed main() {
    scanf( "%lld %lld %lld %lld %lld", &n, &m, &k, &s, &t );
    for( int i = 1;i <= m;i ++ ) scanf( "%lld %lld %lld", &E[i].u, &E[i].v, &E[i].w );
    int ans = solve( 0 );
    for( int i = 1;i <= m;i ++ ) ans = min( ans, solve( E[i].w ) );
    printf( "%lld\n", ans );
    return 0;
}

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您提供的链接是Codeforces的一个问题,问题编号为104377。Codeforces是一个知名的在线编程竞赛平台,经常举办各种编程比赛和训练。GymCodeforces的一个扩展包,用于组织私人比赛和训练。您提供的链接指向了一个问题的页面,但具体的问题内容和描述无法通过链接获取。如果您有具体的问题或需要了解关于Codeforces Gym的更多信息,请提供更详细的信息。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [http://codeforces.com/gym/100623/attachments E题](https://blog.csdn.net/weixin_30820077/article/details/99723867)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [http://codeforces.com/gym/100623/attachments H题](https://blog.csdn.net/weixin_38166726/article/details/99723856)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [CodeforcesPP:Codeforces扩展包](https://download.csdn.net/download/weixin_42101164/18409501)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值