草庐IT

图论-虚拟节点分层建图

Meteor的博客 2023-03-28 原文

图论-虚拟节点分层建图

Nya图最短路

题目链接:Virtual Judge Acwing

题意:
题解:\(a,b\)连一个\(w\)的边,是正常操作,这里有一个重要操作是\(a\)层和\(a+1\)层能直接传送,如果这里使用笨笨的建图方式,那么时间复杂度就是\(O(n^2)\),时间复杂度太高,不太行.

这里有一个聪明的建图方法--->虚拟节点分层建图 具体表示为:将\(a\)层和\(a+1\)层中间建立一个虚拟节点,然后将\(a\)层的所以节点指向虚拟节点,然后虚拟节点指向\(a+1\)层,这样就能实现在\(O(n)\)的时间复杂度情况下进行建图,时间可以接受 具体可以看图:

code

#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define eps 1e-8
#define int128 __int128
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) a/gcd(a,b)*b
#define lowbit(x) (x&-x)
#define all(x) x.begin(), x.end()
#define debug(x...) do { cout<< #x <<" -> "; re_debug(x); } while (0)
void re_debug() { cout<<'\n'; }
template<class T, class... Ts> void re_debug(const T& arg,const Ts&... args) { cout<<arg<<" "; re_debug(args...); }
void cut(){ cout<<'\n'<<"------------"<<'\n';}
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
const int INF=0x3f3f3f3f;
const ll LNF=0x3f3f3f3f3f3f3f3f;
const double PI=acos(-1.0);
const int N=2e5*3;
int e[N],ne[N],h[N],idx;
int w[N];
int dist[N];
int n,m,c;
int t=1;
bool st[N];
void add(int a,int b,int c)
{
    e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
void dijkstra()
{
    priority_queue<PII,vector<PII>,greater<PII>> q;
    q.push({0,1});
    dist[1]=0;
    while(q.size())
    {
        auto v=q.top().second;
        q.pop();
        if(st[v]) continue;
        st[v]=true;
        for(int i=h[v];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(dist[j]>dist[v]+w[i])
            {
                dist[j]=dist[v]+w[i];
                q.push({dist[j],j});
                
            }
        }
    }
}
void solve()
{
    idx=0;//注意一定要清零
    scanf("%d%d%d",&n,&m,&c);
    for(int i=0;i<=n*3;i++)//用到了3n这些点
    {
        dist[i]=INF;
        st[i]=0;
        h[i]=-1;
    }
    vector<vector<int>> depth(n+1+1);
    int max_depth=-1;
    for(int i=1;i<=n;i++)
    {
        int x;
        scanf("%d",&x);
        depth[x].push_back(i);
        max_depth=max(max_depth,x);
    }
    for(int i=1;i<max_depth;i++)
    {
        //这里用到了3*n以上的点,其实n--2n这一层是a层-->a+1层,2n--3n是a+1到a层,注意这是单向边
        for(auto &t:depth[i]) add(t,n+i+1,c);//t层连到t+1层
        for(auto &t:depth[i+1]) add(n+i+1,t,0);/
        for(auto &t:depth[i]) add(2*n+i+1,t,0);
        for(auto &t:depth[i+1]) add(t,2*n+i+1,c);
    }
    for(int i=0;i<m;i++)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        add(a,b,c);
        add(b,a,c);
    }
    dijkstra();
    if(dist[n]==INF) printf("Case #%d: %d\n",t++,-1);
    else printf("Case #%d: %lld\n",t++,dist[n]);
}
int main()
{
    int T=1;
    scanf("%d",&T);
    while(T--) solve();
    return (0^0);
}

Slipper

杭电多校第四场第三题,其实这里就是n层能跳到n+k层了,那么其实就是板子了

#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define eps 1e-8
#define int128 __int128
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) a/gcd(a,b)*b
#define lowbit(x) (x&-x)
#define all(x) x.begin(), x.end()
#define debug(x...) do { cout<< #x <<" -> "; re_debug(x); } while (0)
void re_debug() { cout<<'\n'; }
template<class T, class... Ts> void re_debug(const T& arg,const Ts&... args) { cout<<arg<<" "; re_debug(args...); }
void cut(){ cout<<'\n'<<"------------"<<'\n';}
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,int> PII;
const int INF=0x3f3f3f3f;
const ll LNF=0x3f3f3f3f3f3f3f3fll;
const double PI=acos(-1.0);
const int N=2000010*4;
int e[N],ne[N],w[N],h[N],idx;
int depth[N];
ll dist[N];
bool st[N];
int n;
int max_depth=-1;
int s,t;
void add(int a,int b,int c)
{
    e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u,int father)//处理出来这个深度
{
    depth[u]=depth[father]+1;
    max_depth=max(max_depth,depth[u]);
    for(int i=h[u];i!=-1;i=ne[i])
    {
        int j=e[i];
        if(j==father) continue;
        dfs(j,u);
    }
}
void dijkstra()
{
    priority_queue<PII,vector<PII>,greater<PII>> q;
    dist[s]=0;
    q.push({0,s});
    while(q.size())
    {
        auto v=q.top().second;q.pop();
        if(st[v]) continue;
        st[v]=true;
        for(int i=h[v];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(dist[j]>dist[v]+w[i])
            {
                dist[j]=dist[v]+w[i];
                q.push({dist[j],j});
            }
        }
    }
}
void solve()
{
    idx=0;
    cin>>n;
    for(int i=0;i<=n*3+10;i++)
    {
        h[i]=-1;
        dist[i]=LNF;
        st[i]=0;
    }
    for(int i=0;i<n-1;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        add(a,b,c);
        add(b,a,c);
    }
    int k,p;
    cin>>k>>p;
    
    dfs(1,-1);
    vector<vector<int>> depths(max_depth+k+1);
    for(int i=1;i<=n;i++)
    {
        depths[depth[i]].push_back(i);
    }
    for(int i=1;i<=max_depth;i++)
    {
        for(auto &t:depths[i]) add(t,n+i+1,p);//t层连到t+k层
        for(auto &t:depths[i+k]) add(n+i+1,t,0);//注意不要重复
        for(auto &t:depths[i]) add(2*n+i+1,t,0);
        for(auto &t:depths[i+k]) add(t,2*n+i+1,p);
    }
    cin>>s>>t;
    dijkstra();
    if(dist[t]==LNF) cout<<"-1"<<'\n';
    else cout<<dist[t]<<'\n';
}
int main()
{
    IOS;
    int T=1;
    cin>>T;
    while(T--) solve();
    return 0^0;
}

有关图论-虚拟节点分层建图的更多相关文章

  1. 在VMware16虚拟机安装Ubuntu详细教程 - 2

    在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主

  2. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  3. 区块链入门教程(6)--WeBASE-Front节点前置服务安装 - 2

    文章目录1.任务背景2.任务目标3.相关知识点4.任务实操4.1安装配置JDK4.2启动FISCOBCOS4.3下载解压WeBASE-Front4.4拷贝sdk证书文件4.5启动节点4.6访问节点4.7检查运行状态5.任务总结1.任务背景FISCOBCOS其实是有控制台管理工具,用来对区块链系统进行各种管理操作。但是对于初学者来说,还是可视化界面更友好,本节就来介绍WeBASE管理平台,这是一款微众银行开源的自研区块链中间件平台,可以降低区块链使用的门槛,大幅提高区块链应用的开发效率。微众银行是腾讯牵头设立的民营银行,在国内民营银行里还是比较出名的。微众银行参与FISCOBCOS生态建设,一定

  4. ruby - 选择包含子节点内文本的父节点 - 2

    基本上我想选择一个节点(div),其中它的子节点(h1,b,h3)包含指定的文本。Childtext1Childtext2...Childtext3我期待的是/html/div/而不是/html/div/h1我在下面有这个,但不幸的是返回了child,而不是div的xpath。expression="//div[contains(text(),'Childtext1')]"doc.xpath(expression)我期待的是/html/div/而不是/html/div/h1那么有没有一种方法可以简单地使用xpath语法来做到这一点? 最佳答案

  5. ruby-on-rails - Rails 验证虚拟属性 - 2

    我这个模型:classBunny每当我提交一个表单来创建这个模型时,我都会收到以下错误:#的未定义方法“number_before_type_cast” 最佳答案 我通过将此方法添加到我的Bunny模型中解决了这个问题:defnumber_before_type_castnumberend我不喜欢它,但我想在有人发布更好的解决方案之前它会起作用。 关于ruby-on-rails-Rails验证虚拟属性,我们在StackOverflow上找到一个类似的问题: h

  6. ruby - 删除指定节点之后的所有节点 - 2

    这个问题在这里已经有了答案:Nokogiri:SelectcontentbetweenelementAandB(3个答案)关闭2年前。我正在从url中抓取文本的div,并想删除具有backtotop类的段落下方的所有内容。我在stackoverflow上看到了一段遍历代码片段,看起来很有希望,但我不知道如何将它合并,所以@el只包含第一个p.backtotop之前的所有内容分区我的代码:@doc=Nokogiri::HTML(open(url))@el=@doc.css("div")[0]end遍历片段:doc=Nokogiri::HTML(code)stop_node=doc.css

  7. ruby - 如何从 Chef 说明书中的库访问当前节点? - 2

    我正在尝试为ChefRecipe编写一个库,以简化一些常见的搜索。例如,我希望能够在cookbook/libraries/library.rb中执行类似的操作,然后从同一Recipe中的Recipe中使用它:moduleExampledefself.search_attribute(attribute_name)returnsearch(:nodes,node[attribute_name])endend问题是,在Chef库文件中,node对象或search函数都不可用。似乎可以使用Chef::Search::Query.new().search(...)进行搜索,但我找不到任何可以访

  8. ruby - 如何使用Nokogiri和XPath获取具有多个属性的节点 - 2

    我正在尝试使用Nokogiri来解析带有一些相当古怪的标记的HTML文件。具体来说,我正在尝试获取同时定义了id、多个类和样式的div。标记看起来像这样:titleListofstuff我正在尝试获取里面的问题.我可以毫无问题地获得具有单个id属性的div,但我想不出一种方法让Nokogiri获取具有和两个id类的div。所以这些工作正常:content=@doc.xpath("//div[id='foo']")content=@doc.css('div#foo')但是这些不返回任何东西:content=@doc.xpath("//div[id='bar']")content=@doc

  9. ruby - 您如何将 S3 理解为 Ruby 中的分层目录结构? - 2

    有没有人成功地将S3存储桶读取为子文件夹?文件夹1--子文件夹2----文件3----文件4--文件1--文件2文件夹2--子文件夹3--文件5--文件6我的任务是读取文件夹1。我希望看到子文件夹2、文件1和文件2,但看不到文件3或文件4。现在,因为我将存储桶键限制为prefix=>'folder1/',你仍然会得到file3和4,因为它们在技术上具有folder1前缀。似乎真正做到这一点的唯一方法是吸收folder1下的所有键,然后使用字符串搜索从结果数组中实际排除file3和file4。有没有人有过这方面的经验?我知道像Transmit和Cyber​​duck这样的FTP风格的S3

  10. 【云计算】私有云在VMware下虚拟机的创建与配置(图文教程) - 2

    【适用平台】私有云   说明:完成私有云部分是需要两台虚拟机的,分别为controller、compute两个节点,但我们只需配置一台,然后克隆就方便多啦!需要用到的映射文件:关于vm的安装我就不介绍的,毕竟挺简单的,下面让我们看看基于私有云模块中,虚拟机的搭建吧。1、创建新的虚拟机,这里一般我会选择自定义,毕竟后面的配置都要根据私有云相关来进行搭建,会比较复杂。(如果是基础的可以选择典型,典型的满足一般虚拟机的配置) 2、选择稍后安装操作系统会比较方便后续的选择,这里你也可以自己选择自己的映像文件(但不建议)  3、我们是基于Linux下操作的,所以选择Linux客户机操作系统,版本选择自己

随机推荐