首页 > 其他分享 >【模板】图论

【模板】图论

时间:2024-07-28 11:06:30浏览次数:12  
标签:图论 int LL pb v2 dfn 模板 dis

图论

  • \(k\) 短路

  • 圆方树

int n,nn;
struct {
	Vi e[N];
	void adde(int x,int y) { e[x].pb(y), e[y].pb(x); }
} tr;
struct {
	int ind,dfn[N],low[N];
	bool cut[N];
	Vi e[N];
	void tarjan(int rt,int u) {
		static int t,s[N];
		dfn[u] = low[u] = ++ind, s[++t] = u;
		int son = 0;
		for(int v : e[u])
			if( dfn[v] ) ckmin(low[u],dfn[v]);
			else {
				tarjan(rt,v), ckmin(low[u],low[v]);
				if( dfn[u] <= low[v] ) {
					if( u != rt || son++ ) cut[u] = 1;
					++nn, tr.adde(nn,u);
					do tr.adde(nn,s[t]); while( v != s[t--] );
				}
			}
	}
	void main() {
		For(i,1,n) if( !dfn[i] ) tarjan(i,i);
	}
} G;
  • SCC 缩点
int nn,ind,dfn[N],low[N],id[N];
Vi scc[N],ee[N];
void tarjan(int u) {
	static int t,s[N];
	dfn[u] = low[u] = ++ind, s[++t] = u, id[u] = -1;
	for(auto [v,w] : e[u])
		if( !dfn[v] ) tarjan(v), ckmin(low[u], low[v]);
		else if( !~id[v] ) ckmin(low[u], dfn[v]);
	if( dfn[u] == low[u] ) {
		++nn;
		do id[s[t]] = nn, scc[nn].pb(s[t]); while( u != s[t--] );
	}
}
signed main() {
	For(i,1,n) if( !dfn[i] ) tarjan(i);
	For(u,1,n) for(int v : e[u]) if( id[u] != id[v] ) ee[id[u]].pb(id[v]);
}

  • Prufer 序列

\(n\) 个点的完全图的生成树 \(\leftrightarrow\) 长度为 \(n-2\) 值域为 \([1,n]\) 的序列

// tree -> prufer
For(i,1,n-1) ++deg[fa[i]];
for(int i = 1, u = 1; i <= n-2; ++i, ++u) {
	while( deg[u] ) ++u; p[i] = fa[u];
	for(; i <= n-2 && !--deg[p[i]] && p[i] < u; ++i) p[i+1] = fa[p[i]];
}
// prufer -> tree
For(i,1,n-2) ++deg[p[i]]; p[n-1] = n;
for(int i = 1, u = 1; i < n; ++i, ++u) {
	while( deg[u] ) ++u; fa[u] = p[i];
	for(; i < n && !--deg[p[i]] && p[i] < u; ++i) fa[p[i]] = p[i+1];
}
  • ST 表 LCA
int n,rt,dfn[N],st[][N];
Vi e[N];
int _min(int u,int v) { return dfn[u]<dfn[v] ? u : v; }
void dfs(int u,int fa) {
	static int ind;
	dfn[u] = ++ind, st[0][ind] = fa;
	for(int v : e[u]) if( v != fa ) dfs(v,u);
}
int lca(int u,int v) {
	if( u == v ) return u;
	if( (u=dfn[u]) > (v=dfn[v]) ) swap(u,v);
	int k = __lg(v-u++);
	return _min(st[k][u],st[k][v-(1<<k)+1]);
}
signed main() {
	dfs(rt,0);
	For(i,1,) For(j,1,n-(1<<i)+1) st[i][j] = _min(st[i-1][j],st[i-1][j+(1<<i-1)]);
}
  • tarjan LCA

  • 虚树

namespace T {
int dfn[N];
int lca(int x,int y) {}
}
namespace VT {
using namespace T;
bool is1[N];
Vi v2,e[N];
void adde(int x,int y) { e[x].pb(y), e[y].pb(x); }
void main(Vi &v1) {
	{ // build
		v1.resize(read()); for(int &i : v1) cin>>i, is1[i] = 1;
		auto cmp = [](int x,int y) { return dfn[x] < dfn[y]; };
		v2 = v1, sort(all(v2),cmp);
		Rep(i,1,sz(v1)) v2.pb(lca(v2[i-1],v2[i]));
		v2.pb(1), sort(all(v2),cmp), v2.erase(unique(all(v2)),v2.end());
		Rep(i,1,sz(v2)) adde(lca(v2[i-1],v2[i]),v2[i]);
	}
	{ // clear
		for(int i : v1) is1[i] = 0;
		for(int i : v2) e[i].clear();
	}
}
}

网络流

  • 最大流/最小割

流量 long long

namespace flow {
const int N = ;
const LL inf = 0x3f3f3f3f3f3f3f3f;
int fn,S,T,head[N],dis[N];
struct Edge {
	int to,b; LL c;
	Edge(int to=0,int b=0,LL c=0):to(to),b(b),c(c){}
}; vector<Edge> e[N];
void init() { S = 1, T = fn = 2; }
void addedge(int x,int y,LL z) { e[x].pb(y,sz(e[y]),z), e[y].pb(x,sz(e[x])-1,0); }
bool bfs() {
	static int l,r,q[N];
	memset(head+1,0,sizeof(int)*fn), memset(dis+1,0,sizeof(int)*fn);
	dis[S] = 1, q[l=r=1] = S;
	while( l <= r ) {
		int u = q[l++];
		for(auto [v,b,c] : e[u]) if( c && !dis[v] )
			{ dis[v] = dis[u]+1, q[++r] = v; if( v == T ) return 1; }
	}
	return 0;
}
LL dfs(int u,LL f) {
	if( u == T ) return f;
	LL use = 0;
	for(int &i = head[u]; i < sz(e[u]); ++i)
		if(auto &[v,b,c] = e[u][i]; c && dis[u]+1 == dis[v] ) {
			if( LL g = dfs(v,min(c,f-use)) ) {
				c -= g, e[v][b].c += g;
				if( (use+=g) == f ) return f;
			} else dis[v] = 0;
		}
	return use;
}
LL dinic() { LL mf=0; while( bfs() ) mf += dfs(S,inf); return mf; }
} using flow::fn; using flow::S; using flow::T; using flow::addedge;
  • 最小费用最大流

流量 int,费用 long long

namespace flow {
const int N = , inf = 0x3f3f3f3f; const LL infl = 0x3f3f3f3f3f3f3f3f;
int fn,S,T,mf,mc,head[N],dep[N]; LL dis[N];
bitset<N> vis;
struct Edge {
	int to,b,c; LL w;
	Edge(int to=0,int b=0,int c=0,LL w=0):to(to),b(b),c(c),w(w){}
}; vector<Edge> e[N];
void init() { S = 1, T = fn = 2; }
void addedge(int x,int y,int z=1,LL w=0)
	{ e[x].pb(y,sz(e[y]),z,w), e[y].pb(x,sz(e[x])-1,0,-w); }
bool spfa() {
	static queue<int> q; 
	memset(head+1,0,sizeof(int)*fn), memset(dis+1,0x3f,sizeof(dis[0])*fn);
	dis[S] = 0, q.emplace(S);
	while( q.size() ) {
		int u = q.front(); q.pop(); vis[u] = 0;
		for(auto& [v,b,c,w] : e[u]) if( c && dis[u]+w < dis[v] ) {
			dis[v] = dis[u]+w, dep[v] = dep[u]+1;
			if( !vis[v] ) vis[v] = 1, q.emplace(v);
		}
	}
	return dis[T] < infl;
}
int dfs(int u,int f) {
	if( u == T ) return f;
	int use = 0;
	for(int &i = head[u]; i < sz(e[u]); ++i) {
		auto& [v,b,c,w] = e[u][i];
		if( c && dis[u]+w == dis[v] && dep[u]+1 == dep[v] ) {
			if( int g = dfs(v,min(c,f-use)) ) {
				c -= g, e[v][b].c += g;
				if( (use+=g) == f ) break;
			} else dis[v] = -1;
		}
	}
	return use;
}
void dinic() { while( spfa() ) { int f = dfs(S,inf); mf += f, mc += f * dis[T]; } }
} using flow::fn; using flow::S; using flow::T; using flow::addedge;
  • 负圈最小费用最大流

有源汇上下界

namespace flow {
const int N = , inf = 0x3f3f3f3f; const LL infl = 0x3f3f3f3f3f3f3f3f;
int s,t,fn,S,T,mf,mc,dlt[N],head[N],dep[N]; LL dis[N];
bitset<N> vis;
struct Edge {
	int to,b,c; LL w;
	Edge(int to=0,int b=0,int c=0,LL w=0):to(to),b(b),c(c),w(w){}
}; vector<Edge> e[N];
void addedge(int x,int y,int z=1,LL w=0) {
	auto adde=[](int x,int y,int z,LL w)
		{ e[x].pb(y,sz(e[y]),z,w), e[y].pb(x,sz(e[x])-1,0,-w); };
	if( w >= 0 ) adde(x,y,z,w);
	else mc += z*w, adde(y,x,z,-w), dlt[x] -= z, dlt[y] += z;
}

void main() {
	For(i,1,fn)
		if( dlt[i] > 0 ) addedge(S,i,dlt[i]);
		else if( dlt[i] < 0 ) addedge(i,T,-dlt[i]);
	addedge(t,s,inf);
	dinic();
	mf = 0, S = s, T = t, dinic();
}
} using flow::fn; using flow::S; using flow::T; using flow::addedge;

标签:图论,int,LL,pb,v2,dfn,模板,dis
From: https://www.cnblogs.com/ft61/p/18327973

相关文章

  • C++模板——泛型编程
    目录1.什么是泛型编程2.函数模板2.1定义格式2.2实例化及原理 2.3参数匹配原则3.类模板 3.1定义格式3.2实例化 4.非类型模板参数 5.模板的特化 5.1概念5.2函数模板和类模板特化6.模板的分离编译 1.什么是泛型编程 如何实现一个通用的加......
  • 片 - 图论 - 1
    欢迎来看“片”(的简介)由于-\(看片\)-生涯转瞬即逝,于是我选择对“\(片\)”进行一定的总结:相信你一定看懂了由于开始的时间有一点晚,就姑且认为我以后会慢慢补充吧......回到总部\(B3609\)\([图论与代数结构\)\(701]\)\(强连通分量\)解:tarjan,强连通分量\(\mathcal{RT}\)......
  • 【C++第九章】初阶模板
    C++模板初阶模板介绍......
  • 【Go】基于 Go 1.19 的站点模板爬虫【实战演练版】
    0.前言Go语言,也被称为Golang,是由Google开发的一种开源编程语言,它在2009年首次发布,并在2012年正式开源。Go语言被设计用来简化大型软件的开发,特别注重并发编程和内存安全。0.1特点静态类型:Go是静态类型语言,这意味着类型在编译时已经确定,有助于在编译阶段捕捉错误......
  • 树模板
    structTree{intn,d=0;//顶点,直径,树中心//自顶向下u到其叶子结点最远距离d1,次长距离d2(与最长路径无公共边)//p1,p2表示结点u向下更新时是由哪个结点更新来的//up表示结点u向上到祖宗结点的最远距离vector<int>d1,d2,p1,p2,up;vector<vector<i......
  • Django 仅发送更改响应而不是完整模板
    如何只发送一条警报消息来响应请求,而不必发送专门为警报制作的模板?我正在使用Javascript异步调用。我只需要警报html响应即可呈现InnerHTML查看@login_required(login_url="/login/")@csrf_protectdefusersave(request):msg=messages.add_message(req......
  • 使用 Flask 时,为什么这个 html 模板不能在 Web 浏览器中呈现抓取的网站数据?
    每当我在终端中打印出抓取的数据时,它都会很好地显示抓取的数据,但每当我尝试使用PythonFlask提供它时,我使用的HTML模板不会在Web浏览器中呈现数据。如果您能帮我修复此代码。Python(Flask)文件:fromflaskimportFlask,render_templatefrombs4importBeautifulSoup......
  • 网站源码教育机构pbootcms模板网页设计主题
    教育机构的网站设计分享我很高兴向大家介绍我刚刚制作的教育机构的网站设计。友好的站点界面,是打动访客的第一步。教育机构网站的主题网站设计旨在向访客展示机构的专业性、教学质量以及服务内容,同时提供一个用户友好的界面,使访客能够轻松地获取所需信息、进行互动和报名。以......
  • nuclei模板编写总结
    一、脚本的语法格式大小写敏感缩进:使用缩进表示层级关系,YAML使用空格进行缩进,通常每个缩进级别为两个空格。键值对:YAML通过键值对来存储数据,键和值之间用冒号:分隔。列表:使用短横线-来表示列表中的项。注释:以#开头的行是注释。字符串:字符串可以不使用引号,也可以使用单引号......
  • 51nod-基因匹配+luogu-【模板】最长公共子序列
    https://www.luogu.com.cn/problem/P1439https://class.51nod.com/Html/Textbook/ChapterIndex.html#textbookId=126&chapterId=338以上两个都是特例,一个是每个元素不重复,一个是每个元素均有5个。正确性说明参考:https://www.luogu.com.cn/article/1bcs9052由于一般情况可能出......