首页 > 其他分享 >NFLS 省选模拟 过路费

NFLS 省选模拟 过路费

时间:2024-02-28 15:44:26浏览次数:15  
标签:省选 路径 NFLS int 过路费 条边 长度 最优 dis

前言

这道题正向思考是比较难以想出来的,蕴含了一类解题的思路,同时也可以当作一类板子题记忆。

题面

Link

给定一个有向图,求 \(s\) 到 \(t\) 的最短路径。特殊点在于,对于一条路径, 如果经过的边数小于等于 \(k\),那么该路径总长度为构成该路径的所有边的长度之和;否则为该路径上最长的 \(k\) 条边的长度之和。

解法

步骤

设答案为 \(ans\),我们先将 \(ans\) 赋值为原图的最短路。然后依次枚举每条边的长度 \(w_x\),对于每个 \(w_x\),我们将原图上每条边的长度 \(w_i\) 都减去 \(w_x\),如果减去后为负数就设为 \(0\),即 \(w_i=\max\{w_i-w_x,0\}\),求出此时的最短路,加上 \(k\times w_x\) 后更新 \(ans\)。

正确性证明

最优路径总边数大于 \(k\) 的情况

假设已经知道了最优解,\(w_x\) 取 \(w_{最优}\) 时生成的图的最短路径上留下的边(我们称边长非零的边为留下的边)的数量一定刚好为 \(k\),最短路径上其他的边边长为 \(0\)。此时最短路径长度为 \(\Large\sum\limits_{E_i\in留下的边}\normalsize (E_i原边长-w_x)\),再加上 \(k\times w_x\) 后刚好等于原图这 \(k\) 条边长度之和。

可以发现对于每次枚举到的 \(w_x\),计算出的解都不会更优于最优解,可以类似理解为答案是具有凸性的:

  • 当 \(w_x < w_{最优}\) 时,由于每条边都相对变长了,显然此时最短路径只会变长不会变短。对于最短路径原先的 \(k\) 条边,它们加上 \(k\times w_x\) 后变回原边长;但此时的最短路径相比最优解最短路径可能还多出来一些非零边,因此此时的答案一定是大于等于最优解最短路径长度的。
  • 当 \(w_x > w_{最优}\) 时,令此时最短路径上留下的边为 \(k'\),由于边权减去的变多了,那么肯定 \(k' < k\),假如说我们仍强行按照最优解的那 \(k\) 条边统计答案,并且让多出来的 \((k-k')\) 条边保留负数而不变为 \(0\),此时 \(\Large\sum\limits_{E_i\in最优解的k条边}\normalsize (E_i原边长-w_x) + k\times w_x\) 应该是等于最优解长度的,问题是实际上式子为 \(\Large\sum\limits_{E_i\in最优解的k条边}\normalsize \max\{(E_i原边长-w_x),0\} + k\times w_x\),即不会保留负数,此时统计出的答案将会大于最优解。如果还是没懂可以试着自己手推几个例子,简明扼要的理解就是由于“减去后若是负数就强制设为 \(0\),减的变少了,但加回来的还是一样”导致了答案反而变大。

另外,为什么只需要枚举每条边的长度,而不是枚举所有长度(\(1,2,3,\dots,MAXN)\)?

假设有两条边的长度分别为 \(w_1\)​ 和 \(w_2\)​(\(w_1 < w_2\)​),可以发现如果枚举 \(w_x\in (w_1,w_2)\)​,边权变为 \(0\)​ 的边与 \(w_x=w_1\)​ 时一致,并且与上文 \(w_x > w_{最优}\)​ 同理,答案只会相等或者更劣。因此没必要考虑两条边长之间的长度,最优的 \(w_x\)​​ 一定是某一条边的边长,解具有离散性。

因此这样一定会枚举到最优解。

最优路径总边数小于等于 \(k\)​ 的情况

这种情况说明原图的最短路即为总边数小于等于 \(k\) 的最短路,因此在最开始就用原图最短路更新 \(ans\)。

代码

#include<bits/stdc++.h>
using namespace std;
template<class T>inline void rd(T &x){
    T res=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1; ch=getchar();}
    while(isdigit(ch)){res=res*10+ch-'0';ch=getchar();}
    x=res*f;
}
template<class T>inline void wt(T x){
    if(x<0){x=-x;putchar('-');}
    if(x>9) wt(x/10);
    putchar(x%10+'0');
}
typedef long long LL;
typedef pair<LL,int> pli;
const int MAXN=1005,MAXM=2005;
int n,m,k,s,t,ecnt=0,head[MAXN];
LL ans;
struct EDGE{
    int v,w,nxt;
}e[MAXM];
inline void add(int u,int v,int w){
    e[++ecnt].v=v;
    e[ecnt].w=w;
    e[ecnt].nxt=head[u];
    head[u]=ecnt;
}
vector<int>price;
inline LL dijkstra(const int &val){
    static bitset<MAXN>vis;
    static LL dis[MAXN];
    priority_queue<pli,vector<pli>,greater<pli> >pq;
    vis.reset();memset(dis,0x3f,sizeof(dis));
    dis[s]=0;pq.push(make_pair(0,s));
    while(!pq.empty()){
        int u=pq.top().second,v;pq.pop();
        LL w;
        if(vis[u]) continue;
        vis[u]=1;
        for(int i=head[u];i;i=e[i].nxt){
            v=e[i].v;
            w=max(e[i].w-val,0);
            if(dis[v]>dis[u]+w){
                dis[v]=dis[u]+w;
                pq.push(make_pair(dis[v],v));
            }
        }
    }
    return dis[t];
}
int main(){
    rd(n);rd(m);rd(k);rd(s);rd(t);
    for(int i=1,x,y,z;i<=m;i++){
        rd(x);rd(y);rd(z);
        add(x,y,z);
        price.push_back(z);
    }
    sort(price.begin(),price.end());
    unique(price.begin(),price.end());
    ans=dijkstra(0);
    for(auto it:price){
        ans=min(ans,dijkstra(it)+1LL*k*it);
    }
    wt(ans);
    return 0;
}

总结

这种题的特征是答案具有凸性,含有“恰好 \(k\) 个”类似的描述,并且答案是离散的可以枚举,即可以尝试用本文提到的思路作答。

另外,这种做法与wqs二分有思想上的类似之处,可以互相参考。

标签:省选,路径,NFLS,int,过路费,条边,长度,最优,dis
From: https://www.cnblogs.com/SkyNet-PKN/p/18040650

相关文章

  • 联合省选 2024 游击
    \(Day-18\)被拉来集训,被后门各种大神打爆了。模拟赛天天保龄,人不为己,天诛地灭。\(Day-12\)sky开学。从当天开始,状态稳定直线下滑,感觉很难调过来了。模拟赛又双叒叕被打爆了,天天做题开摆,混日子很失败。\(Day-5\)筹集,很困。没有状态怎么办?没有状态怎么办?没有状态怎么办?没有......
  • 2024 省选复习 (updating)
    前言快省选了,在复习,但是不知道干什么。所以就写点东西吧。就是瞎写写,所以可能有很多错误,如果发现了欢迎指出。常见错误&注意事项数组不能开大,也不能开小题目要求什么千万不能读错,最好手算一下样例算法复习树状数组进阶P6619原本是树状数组二分的模板题,但是用......
  • NOI 2024省选OIFC模拟21 蒲巴巴 超繁做法
    题目描述一年一度的PuBaBa杯开始了!今年的PuBaBa杯总共有\(n\)个选手来参加,编号分别为\(1,2,\cdots,n\),他们的水平按编号依次递增,所以他们过的题目数量单调不降。作为本场比赛的出题人,PuBaBa总共出了\(m\)道题,他希望第\(i\)道题至少有\(l_i\)个选手通过,至多有\(......
  • NFLS 省选模拟 序列
    题面Link给定一个长度为\(n\)的序列\(a\),可以进行无限次下列操作:对于\(i\in[2,n-1]\),依次执行(而不是择一执行)\[a[i-1]+=a[i]\\a[i+1]+=a[i]\\a[i]=-a[i]\]求最小的\(\max^n_{i=1}|a[i]|\)思路考虑一次操作对于序列前缀和的影响,对于\(x,y,z\),其前缀和为\(x,x+y......
  • 91st 2024/2/26 省选联赛训练-1st
    迟来的新年快乐!这次的机会挺难得的,初三了,好说歹说从学校里跑出来训练了,就一定要珍惜时间进入正题今天的比赛难度高,但也没有省选那么难属于是思路比较难想那类T1题目有些疑惑,但总体表达还可,应该是太久没接触这种表达较专业的题目而一时难以适应看题需要认真且专心调代码时状......
  • AC475A 2024省选联测26 博弈
    题意两个人在一张DAG上移动棋子,每个格子的颜色为黑/白。每次操作可以移动一个格子颜色和自己相同的棋子。不能走的人输掉游戏。先手为白色,问所有放棋子的\(2^n\)种方案,先手必胜有多少。Sol不难发现,自己颜色内的棋子不会被对方偷走,也就是说,想控制所有棋子使得对方判负,......
  • 省选 数学
    直接对除法取模会出错,需要变成\(((a\modp)\times(\frac{1}{b}\modp))\modp\)的形式。性质:两个对\(p\)同余的数加减乘上同一个数后依然对\(p\)同余。矩阵乘法:\(c_{i,j}=\sum\limits_1^ka_{i,k}\timesb_{k,j}\)。单位矩阵:对角线上为\(1\)的矩阵。注意,只有\(n\time......
  • 省选2024
    作为一个高二且NOIP只有300分的江苏oier,压力还是有点大的。Day-?得知noip只占30%,但是省队名额只有12个。算了一下,大概我考的和去年水平一样,应该就差不多了,其实可以对标一下ybw。虽然自己水平提高确实很多,但是还是感觉很没底。毕竟去年感觉自己打的很爆炸,结果后来发现我只......
  • 20240223【省选】模拟
    挂30分,还有40分不好说。T2挂的10分应该是字符串常数大,以及那个求LCA珂以优化掉但我人傻没搞。T3的20分就是纯粹脑抽。以后少用stringT1结论题,想错了以为很简单,实际上也很简单,但是我菜。设\(f(x)\)为\(x\)的期望质量,打表使用大眼观察法猜不出这个性质:如果\(x\)为一些质数......
  • 2024省选模拟26联测23
    T1首先,存在一个显然的事情:若集合\(S\)满足要求,那么\(S\)的任何子集也满足要求。还有一个比较显然的事实:对于一个合法的集合,其每个元素的位置一定在范围的交内。难道要用奇怪的容斥???但是好像根本容斥不了。。。。哈哈。能不能考虑减去不合法的状态?也许可以连边找完全图???好......