首页 > 其他分享 >【题解】Luogu[P9504] 『MGOI』Simple Round I C. 魔法禁林

【题解】Luogu[P9504] 『MGOI』Simple Round I C. 魔法禁林

时间:2023-08-06 20:25:55浏览次数:46  
标签:MGOI vis int 题解 times Simple 100 NR dis

Link

这题我们发现如果直接去枚举生命和法力值显然是不行的,又看到说最小的生命值,不禁想到最短路,但是怎么跑?

我们令经过一条边之前魔力值为 \(k\),那么该边的边权为 \(\lfloor\dfrac{w}{k}\rfloor\),于是我们讲题目转化为了边权为 \(\lfloor\dfrac{w}{k}\rfloor\) 时 \(s\) 到 \(t\) 的最短路径。

我们不知道最短路径一共要经过多少条边,也就无法知道初始魔力值究竟有多少。那我们不妨反着想,考虑从 \(t\) 到 \(s\) 的最短路径,这时我们就不用知道初始魔力值是多少,而是每经过一个边,就将 \(k\leftarrow k+1\)。

但是此时仍无法直接跑最短路,因为每一次不同时刻经过一条边,他的边权都是不一样的。此时数据范围 \(w\leq 100\) 很好的提示了我们。

妈妈,我会拆点分层图!

我们将原本的一个点拆成 \(100\) 个点,因为 \(w\) 最大为 \(100\),若经过的边数(即魔力值)\(k>100\),那么他的边权 \(w\) 就必然为 \(0\),我们就不需要考虑了,因为不会对我们的答案产生影响。

于是对于点 \(x\),我们将其拆成 \(100\) 个点 \(x\times 100+i(1\leq i\leq 100)\),其中的 \(i\) 表示在 \(x\times 100+i\) 这个点时的魔力值为 \(i\),于是显然的对于两个点 \(u,v\),其边权为 \(w\),若其在原始图上有边相连,那么我们就在分层图上将 \(u\times 100 +i(1\leq i < 100)\) 与 \(v\times 100 +i+1\) 相连,其边权为 \(\lfloor\dfrac{w}{i}\rfloor\)。

最后也就很简单了,我们在新的分层图上跑一遍 \(t\)(新图上为 \(t\times 100 +1\)) 到 \(s\) 的最短路,最后在 \(s\) 点的所有层里面找最小值即为最终答案。

#include<bits/stdc++.h>
using namespace std;
const int NR=3e6;
const int MX=2e4;
int n,m,s,t;
vector<int>e[NR],g[NR];
void add(int u,int v,int w){
    e[u].push_back(v),g[u].push_back(w);
}
bool vis[NR];
int dis[NR],ans;
queue<int>q;
void spfa(int _s){
    memset(vis,false,sizeof(vis));
    memset(dis,0x3f3f3f3f,sizeof(dis));
    ans=dis[0];
    q.push(_s),vis[_s]=true,dis[_s]=0;
    while(!q.empty()){
        int u=q.front();q.pop();
        vis[u]=false;
        for(int i=0;i<e[u].size();++i){
            int v=e[u][i],w=g[u][i];
            if(dis[v]>dis[u]+w){
                dis[v]=dis[u]+w;
                if(!vis[v])q.push(v),vis[v]=true;
            }
        }
    }
}
int main(){
    cin>>n>>m>>s>>t;
    for(int i=1,u,v,w;i<=m;++i){
        cin>>u>>v>>w;
        for(int j=1;j<100;++j){
            add(u*100+j,v*100+j+1,w/j);
            add(v*100+j,u*100+j+1,w/j);
        }
    }
    spfa(t*100+1);
    for(int i=s*100+1;i<=s*100+100;++i)
        ans=min(ans,dis[i]);
    cout<<ans<<endl;
    return 0;
}

标签:MGOI,vis,int,题解,times,Simple,100,NR,dis
From: https://www.cnblogs.com/agrumestly/p/17609919.html

相关文章

  • 【LGR-148-Div.3】洛谷基础赛 #1 & MGOI Round I
    【LGR-148-Div.3】洛谷基础赛#1&MGOIRoundI据说是普及组难度?T1P9502『MGOI』SimpleRoundI|A.魔法数字\(100pts\)题目描述初级魔法士小M的魔法数字是\(2\)。给定一个正整数\(n\),小M需要找到最大的偶数\(m\),使得\(2^m<n\)。又双叒叕是个水题,然后被又双......
  • [ABC310] D~F 题解
    [ABC310]D~F题解D-PeacefulTeams暴力搜索,搜索每个人在的队伍,为了去重,在一个人第一次加入新的队伍之后跳出。bitset<N>st;voiddfs(intu){for(inti=1;i<=m;i++)if(pos[a[i]]&&pos[b[i]]&&pos[a[i]]==pos[b[i]])return;if(u>n)......
  • 【LGR-148-Div.3】洛谷基础赛 #1 & MGOI Round I
    T1简单题,题面十分清晰,就是给我们\(n\),要求使\(2^m<n\)成立的最小偶数\(m\)。(要注意\(log_2N=m,m|2\)的情况)#include<bits/stdc++.h>#definelllonglong#definereregisterusingnamespacestd;constintN=800,INF=0x3f3f3f3f;lln;intmain(){ cin>>n; llk=log......
  • C++动态规划经典试题解析之打家劫舍系列
    1.前言力扣上有几道与打家劫舍相关的题目,算是学习动态规划时常被提及的经典试题,很有代表性,常在因内大大小小的社区内看到众人对此类问题的讨论。学习最好的方式便是归纳总结、借鉴消化,基于这个目的,本文对此类问题也做了讲解,在一些优秀思想的基础上添加了个人观点。闲话少说,进入......
  • P9499 「RiOI-2」change 题解--zhengjun
    思维妙妙题。赛时的错误做法:找到每个点往后进位变优的位置,最多\(O(\log)\)个;然后从前往后能变优就变优,往后贪心进位。hack数据:0133510021022输出:100这样子由于\(1\)到\(2\)不优,而\(1\)到\(3\)个数不够,所以导致无法进位到\(3\)。所以加强一下......
  • CentOS8安装Docker报错问题解决
    问题描述CentOS版本:8.5.2111。#cat/etc/redhat-releaseCentOSLinuxrelease8.5.2111安装准备:#安装所需软件包sudoyuminstall-yyum-utilsdevice-mapper-persistent-datalvm2#设置docker仓库:推荐阿里云sudoyum-config-manager--add-repohttp://mirrors.al......
  • Codeforces Round 890 (Div. 2) supported by Constructor Institute 题解
    A.TalesofaSort关键就是找逆序对记一组逆序对下标为\(l,r\),则求出最大的\(a_l\)即可B.GoodArrays记要构造的GoodArray为\(b\)前置:\(\forall1\lei\len,b_i=1\)然后\(O(n)\)扫一遍看一下有没有重复,有重复就\(b_i\leftarrowb_i+1\)扫完之后,记\(sum=\sum_......
  • Codeforces Round 882 (Div. 2) 题解
    A.TheManwhobecameaGod求出相邻两个元素的差值,去掉前\(m\)个大的差值以后的差值和即为答案B.HamonOdyssey由按位与的性质可以知道,前缀与和的值只会越来越小,只要和为\(0\)的时候我们就清空按位与前缀和,增加一下次数,如果最终次数不为\(0\),特判一下,次数加一即可C.......
  • abc313D 题解
    [abc313DOddorEven]。好有趣捏。我们考虑\(N=K+1\)。设\(s_i\)为\(\displaystyle\sum_{j\neqi}a_j\bmod2\)。因为\(K\)为奇数,我们可以得到\(\displaystyle\sum_{i=1}^{K+1}s_i\equiv\sum_{i=1}^{K+1}a_i\pmod2\)。所以\(a_i=\displaystyle\sum_{i=1}^{K+1}a_i\b......
  • Nule 题解
    1.题意简述:给定一个N行N列的非负整数方阵,从左上角(1,1)出发,只能向下或向右走,且不能到达值为0的方格,求出一条到达右下角的最佳路径,所谓最佳路径是指途径的数的乘积的末尾连续的0最少。2.样例解释:41300082256503015742这个样例有多重走法,这里给出两个:1.1->......