首页 > 其他分享 >分层图的妙用

分层图的妙用

时间:2023-02-19 21:36:15浏览次数:49  
标签:妙用 cur nxt int 短路 分层 cost dis

介绍

分层图是一种很容易理解并且用途广泛的图,多用于求最短路,它其实是普通图最短路的加强版,可以解决一些图论题目的特殊操作,这个特殊操作就是我们去分的“层”。

思想

做分层图的题,只要把题目读懂,明白到底“层”分在哪就能解题,比如说:

给定一张\(n\)个点\(m\)条边的图,给出原点\(s\)和目标点\(t\),可以创造\(k\)次虫洞(不一定要用完),使得任意\(i\)到\(j\)的距离变为\(0\),请求出\(s\)到\(t\)的最短距离

那么,这道题有区别与普通最短路的地方明显就在于可以创造虫洞,而我们需要分的层就体现在创造虫洞的次数,下面我们就用图演示分层算法,假设此时原点为1,目标点为5,可以创造2次虫洞:
在这里插入图片描述
首先我们先将图复制为3份 为什么不是2份?因为一个虫洞也不创建也算一种情况
在这里插入图片描述
然后,对于某个点来说(这里以点4为例),它既有连接本层内的原始边(蓝色),而且我们还可以创造一次虫洞,使得它直接传送到下一个节点,因此应该还要连一条距离为\(0\)的边(红色),但是这条边应该连到\(k+1\)的图的下一个节点,表明我们创造了一次虫洞(\(k=2\)时就不能继续往上连了)
在这里插入图片描述
最后,我们按照这样的规律,将所有的“跨层边”都连起来(彩色边,距离都为0),跑一遍最短路,\(k=0\)时的原点到\(k=u\)时的目标点的最短路就是答案
在这里插入图片描述
因此,分层图仅仅通过多加边的方式解决了最短路中的“自定义”操作,其他步骤与普通最短路无异,而如果要修改最短路算法来达到相同效果,将会是非常麻烦的


实现

那么,相信你已经掌握了分层图的思想,做一道例题试试吧
P4568 [JLOI2011] 飞行路线

这里我采用了多层图存储于同一个数组中,也可以用二维数组更直观

注意本题有个hack数据,hack原理:戳我,直接输出最大\(k\)结点且没有判断\(k\)与\(m\)关系的代码会被hack掉

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
const int MAXN=1e4+5,MAXNK=MAXN*11;
int n,m,k,s,t,dis[MAXNK];
bool vis[MAXNK];
struct EDGE{
    int to,val;
};
vector<EDGE>g[MAXNK];
inline void add(int from,int to,int cost){
    EDGE tmp;
    tmp.to=to;tmp.val=cost;
    g[from].push_back(tmp);
}
void dijkstra(){
    dis[s]=0;
    priority_queue<pii,vector<pii>,greater<pii>>pq;
    pq.push(make_pair(0,s));
    while(!pq.empty()){
        int cur=pq.top().second;pq.pop();
        if(!vis[cur]){
            vis[cur]=1;
            for(auto nxt:g[cur]){
                if(dis[nxt.to]>dis[cur]+nxt.val){
                    dis[nxt.to]=dis[cur]+nxt.val;
                    pq.push(make_pair(dis[nxt.to],nxt.to));
                }
            }
        }
    }
}
int main(){
    ios::sync_with_stdio(false);
    memset(dis,0x3f,sizeof(dis));
    memset(vis,0,sizeof(vis));
    cin>>n>>m>>k>>s>>t;
    for(int i=1,from,to,cost;i<=m;i++){
        cin>>from>>to>>cost;
        add(from,to,cost);
        add(to,from,cost);
        for(int j=1;j<=k;j++){
            add(from+(j-1)*n,to+j*n,0);
            add(to+(j-1)*n,from+j*n,0);
            add(from+j*n,to+j*n,cost);
            add(to+j*n,from+j*n,cost);
        }
    }
    for(int i=1;i<=k;++i)
	{
		add(t+(i-1)*n,t+i*n,0);//这行代码的目的是为了将所有层图的目标点最短路集中在第k层的汇点,hack数据就hack在这里
	}
    dijkstra();
    cout<<dis[t+k*n]<<endl;
    return 0;
}

标签:妙用,cur,nxt,int,短路,分层,cost,dis
From: https://www.cnblogs.com/SkyNet-PKN/p/17135638.html

相关文章

  • 解析大型电商网站系统架构分层设计
    DevOps人员需要了解公司的网站架构设计,如果牵涉了具体的高流量高并发的场景,那么,此时也需要提供实际的解决方案,所以了解网站的分层系统架构设计是非常有必要的。网站架构一般......
  • 辅助栈的妙用
    问题1:栈的压入序列和弹出序列面试题31.栈的压入、弹出序列(模拟,清晰图解)-栈的压入、弹出序列-力扣(LeetCode) 思路:引入一个辅助栈,模拟压入和弹出序列的先入后出......
  • SAS,Stata,HLM,R,SPSS和Mplus分层线性模型HLM分析学生受欢迎程度数据|附代码数据
    全文链接:http://tecdat.cn/?p=10809最近我们被客户要求撰写关于分层线性模型HLM的研究报告,包括一些图形和统计输出。本文用于比较六个不同统计软件程序(SAS,Stata,HLM,R,SPSS......
  • m基于PSO粒子群算法的重采样算法仿真,对比随机重采样,多项式重采样,分层重采样,系统重
    1.算法描述重采样的主要方法有随机重采样,多项式重采样,分层重采样,系统重采样,残差重采样,MSV重采样等。a.随机采样是一种利用分层统计思想设计出来的,将空间均匀划分,粒子......
  • m基于PSO粒子群算法的重采样算法仿真,对比随机重采样,多项式重采样,分层重采样,系统重
    1.算法描述       重采样的主要方法有随机重采样,多项式重采样,分层重采样,系统重采样,残差重采样,MSV重采样等。 a.随机采样是一种利用分层统计思想设计出来的......
  • 妙用Java 8中的 Function接口,消灭if...else
    在开发过程中经常会使用 if...else...进行判断抛出异常、分支处理等操作。这些 if...else...充斥在代码中严重影响了代码代码的美观,这时我们可以利用Java8的Function接......
  • 数仓:分层
    数据来源层ODS(OperationDataStore):数据基本上从源表中拉过来,经过抽取、洗净、传输(ETL)后装入本层,大体上按源业务的分类方式而分类的。数据仓库层DW(DataWarehouse):从OD......
  • springboot的分层结构
    model层:实体类,与数据库中的属性保持一致mapper层:也可以称为DAO层,是数据库CRUD的接口我在学生管理系统中,只是写了这么一句话而已??publicinterfaceSt......
  • 分层图最短路
    板子题双倍经验分层图最短路即为将一平面图建成立体分层的图不同层间用“电梯”相连接具体用途:对于可以选择修改路径长度的最短路能改几次就建几层的电梯也就是说......
  • CSS 3.0中的混合模式的妙用
    给大家分享一个用CSS3.0的混合模式实现的特效,不用给文字设置多种颜色,滚动页面时,能够让文字能够根据背景颜色自动发生改变,效果如下:以下是代码实现,欢迎大家复制粘贴和收藏。<......