首页 > 其他分享 >图论杂项 学习笔记

图论杂项 学习笔记

时间:2023-11-22 19:47:39浏览次数:37  
标签:连边 图论 ch int 笔记 add 区间 杂项 define

图论专题新学的知识点有点太多了,还是新开一篇比较好。

数据结构优化建图

reference:常见优化建图技巧

考虑一个题:CF786B。思考如何维护单点/区间向单点/区间连边:

  • 点对点。直接连就行。

  • 点对区间。开一颗线段树,每个节点代表一段区间,父亲向儿子连权为 \(0\) 的边。点对区间连边时直接向 \(\log n\) 个代表点连边即可。

  • 区间对点。与上边类似,开一颗线段树,儿子向父亲连权为 \(0\) 的边。从 \(\log n\) 个代表点连出去即可。

  • 区间对区间。新建一个虚点为这两个区间做一个中转即可。

回到这个题。这个题需要同时维护点对点,区间对点,点对区间连边,求最短路。开两颗线段树,父亲向儿子连边的是第一颗,儿子向父亲连边的是第二颗。

  • 点对点,从第二颗的叶子连到第一颗的叶子。

  • 点对区间,从第二颗的叶子连到第一颗的区间。

  • 区间对点,从第二颗的区间连到第一颗的叶子。

正确性显然。最短路直接从第二颗线段树上 \(s\) 对应的叶子开始跑即可。注意到此时两颗线段树上对应叶子节点间都要互连权为 \(0\) 的边,因为他们代表的是同一个点。

点击查看代码
#include<bits/stdc++.h>
#define int long long
#define mk make_pair
#define fi first
#define se second
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
using namespace std;
typedef pair<int,int>pii;
const int inf=1e18,N=5e5;
inline int read(){
	int x=0,f=1;char ch=getchar();
	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
	while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
struct edge{
	int v,w,nxt;
}e[4000005];
int tot,head[1000005];
void add(int u,int v,int w){
	e[++tot]=(edge){v,w,head[u]},head[u]=tot;
}
int lf[100005];
void build(int l,int r,int p){
	if(l==r){lf[l]=p;return;}
	int mid=(l+r)>>1;
	add(p,ls(p),0),add(p,rs(p),0);
	add(ls(p)+N,p+N,0),add(rs(p)+N,p+N,0);
	build(l,mid,ls(p));build(mid+1,r,rs(p));
}
void solve(int l,int r,int p,int op,int u,int L,int R,int w){
	if(L<=l&&r<=R){
		if(op==2)add(lf[u]+N,p,w);
		else add(p+N,lf[u],w);
		return;
	}
	int mid=(l+r)>>1;
	if(L<=mid)solve(l,mid,ls(p),op,u,L,R,w);
	if(R>mid)solve(mid+1,r,rs(p),op,u,L,R,w);
}
int d[1000005],vis[1000005];
void dijkstra(int s){
	priority_queue<pii,vector<pii>,greater<pii> >q;
	for(int i=1;i<=N*2;i++)d[i]=inf,vis[i]=0;
	d[s]=0;q.push(mk(d[s],s));
	while(!q.empty()){
		int u=q.top().se;q.pop();
		if(vis[u])continue;
		vis[u]=1;
		for(int i=head[u];i;i=e[i].nxt){
			int v=e[i].v,w=e[i].w;
			if(d[u]+w<d[v])d[v]=d[u]+w,q.push(mk(d[v],v));
		}
	}
}
signed main(){
	int n=read(),m=read(),s=read();build(1,n,1);
	for(int i=1;i<=n;i++)add(lf[i],lf[i]+N,0),add(lf[i]+N,lf[i],0);
	while(m--){
		int op=read();
		if(op==1){
			int u=read(),v=read(),w=read();
			add(lf[u]+N,lf[v],w);
		}
		else{
			int u=read(),l=read(),r=read(),w=read();
			solve(1,n,1,op,u,l,r,w);
		}
	}
	dijkstra(lf[s]+N);
	for(int i=1;i<=n;i++)printf("%lld ",((d[lf[i]]>=inf)?-1:d[lf[i]]));
	return 0;
}

还有一些,学会了再补。

标签:连边,图论,ch,int,笔记,add,区间,杂项,define
From: https://www.cnblogs.com/xx019/p/17850098.html

相关文章

  • 算法学习笔记(41): 朴素多项式算法
    朴素多项式算法-\(O(n^2)\)合集我们并不需要NTT,就算需要,也只是用来优化乘法。多项式求逆对于多项式\(\suma_ix^i\)我们需要构造出一个多项式\(\sumb_ix^i\)使得:\[\begin{cases}a_0b_0=1\\\sum_{i=0}^ka_ib_{k-i}=0&k\ge1\end{cases}\]首先\(......
  • 【笔记】C++系列02:连续的作用域解析运算符::的场景有哪些?
    在C++中,可以使用连续的作用域解析运算符::来访问嵌套的命名空间、类和类成员。这种用法通常在以下场景下出现:命名空间嵌套:当命名空间中存在嵌套的命名空间时,可以使用连续的作用域解析运算符来访问内层命名空间中的成员。例如:namespaceA{namespaceB{namespac......
  • 2023.11.22学习笔记(2)
    跳石头P2678[NOIP2015提高组]跳石头-洛谷|计算机科学教育新生态(luogu.com.cn)佬啊佬啊,我的思路:用数组b去储存它的差分,每一次找到它的最小值,将最小值和它旁边的较小的那个值合并,边界的话就直接合并,总计进行m次合并操作,这个时候再找到它的最小值,就是答案但是如果是枚举......
  • 代码整洁之道笔记3
    四.注释1.若编程语言足够有表达力,就不需要注释2.注释的恰当用法是弥补我们在用代码表达意图时遭遇的失败。注释总是一种失败3.程序员应当负责将注释保持在可维护、有关联、精确的高度,更应该把力气用在写清楚代码上,直接保证无须编写注释4.不准确的注释要比没注释坏得多注释不能......
  • 算法学习笔记(40): 具体数学
    具体数学本文是阅读《具体数学》产生的理解性文本,并且涵盖了部分其他相关的内容。不怎么重要或者太难的东西因为时间问题,我略过了。本文来之不易,请勿机械搬运:原文地址-https://www.cnblogs.com/jeefy/p/17848037.html目录具体数学第二章-和式和式的处理有限微积分分部求和......
  • 代码整洁之道笔记4
    七.错误信息错误处理很重要,但如果它搞乱了代码逻辑,就是错误的做法使用异常而非返回码1.遇到错误时,最好抛出一个异常。调用代码很整洁,其逻辑不会被错误处理搞乱先写Try-Catch-Finally语句1.异常的妙处之一是,它们在程序中定义了一个范围。执行try-catch-finally语句中try部分的......
  • sharding分表应用笔记(四)——踩坑记录
    sharding分表应用笔记(四)——踩坑记录(更新中)目录sharding分表应用笔记(四)——踩坑记录(更新中)1sql语句使用时不带分表关键字段2在事务中触发数据源路由1sql语句使用时不带分表关键字段如果不带分表关键字段,会默认进行全节点域遍历。如果没有预先创建所有的表节点,会报错提示找不......
  • GPG 相关简单笔记
    工作中接触到GPG相关,特此记录下一些简单的用法和需求。使用加密加密是采用公钥进行加密,通常情况下,加密需要指定USER,或者USER-ID指令通常是:gpg-uuser-oencrypted.txt-eorigin.txt签名签名只是让接受者判断,这个文件是不是让你接受的,实际上即使不是以你的用户签名的......
  • 学习笔记11
    关于知识点知识点归纳第十三章TCP/IP和网络编程13.1网络编程简介网络编程是指编写应用程序以实现计算机网络之间的通信和数据交换。网络编程涉及到一系列的技术和协议,包括套接字编程、网络协议(如TCP/IP、HTTP等)、分布式计算技术等。在网络编程中,开发者需要了解网络分层模......
  • 阅读笔记-人月神话
    削足适履这个章节在讲什么?我们很多时候在开发程序的时候都是考虑程序的运行时间和效率,而很少考虑到程序的运行空间问题。现在的存储空间是越来越廉价,我们很少去考虑这些问题。经典的DOS版本的仙剑奇侠传还不到20M,而现在的一个大游戏却是2,3G甚至更大。由于计算机的不断更新换代和......