建图优化
缩点
之前提过,不再多说 link
去无用边优化建图
最为简单的就是去重边,删自环。
稍微升级一点就是最小生成树。
一个例题 CF1095F Make It Connected solution
前后缀优化建图
解决对于一个点向一段前缀或者后缀连边的问题。
具体的做法是将整个区间建立一条长为 的虚链。这条虚链从后往前(这种是前缀,后缀是从前往后)连单向边,每个虚链上的点向真正的点连边。
那么我们连边(打个比方,从 连到前缀 )就只需要从 的实点向 的虚点连一条边即可。如果有边权的话我们只在下图中红边赋予边权,其他边边权为 。复杂度
线段树优化建图
可以解决区间、点之间连边的问题。复杂度都是 的。
点连向区间
建立一颗父亲向儿子连单向边的入边线段树,叶子维护实点。
接下来我们直接像普通的查询区间一样,在树中查找出 个区间,然后点分别向这几个区间连边即可。
区间连向点
建立一颗儿子向父亲连单向边的出边线段树,叶子维护实点。
线段树中找到区间然后区间分别向这个点连边即可。
区间连区间
同时维护入边树和出边树即可。但是直接连是 的,显得比较低端。
考虑统一建一个虚点让区间往那里连边即可。这个叶子节点共用只要两个树中叶子节点维护的编号相同即可。
注意一下这里的边是需要开到 的。
参考代码:
#include<bits/stdc++.h>
#define ll long long
#define db double
#define filein(a) freopen(#a".in","r",stdin)
#define fileot(a) freopen(#a".out","w",stdout)
#define sky fflush(stdout);
#define gc getchar
#define pc putchar
#define Better_IO true
namespace IO{
#if Better_IO==true
char buf[(1<<20)+3],*p1(buf),*p2(buf);
const int lim=1<<20;
inline char gc(){
if(p1==p2) p2=(p1=buf)+fread(buf,1,lim,stdin);
return p1==p2?EOF:*p1++;
}
#define pc putchar
#else
#define gc getchar
#define pc putchar
#endif
inline bool blank(const char &c){
return c==' ' or c=='\n' or c=='\t' or c=='\r' or c==EOF;
}
inline void gs(char *s){
char ch=gc();
while(blank(ch) ) {ch=gc();}
while(!blank(ch) ) {*s++=ch;ch=gc();}
*s=0;
}
inline void gs(std::string &s){
char ch=gc();s+='#';
while(blank(ch) ) {ch=gc();}
while(!blank(ch) ) {s+=ch;ch=gc();}
}
inline void ps(char *s){
while(*s!=0) pc(*s++);
}
inline void ps(const std::string &s){
for(auto it:s)
if(it!='#') pc(it);
}
template<class T>
inline void read(T &s){
s=0;char ch=gc();bool f=0;
while(ch<'0'||'9'<ch) {if(ch=='-') f=1;ch=gc();}
while('0'<=ch&&ch<='9') {s=s*10+(ch^48);ch=gc();}
if(ch=='.'){
db p=0.1;ch=gc();
while('0'<=ch&&ch<='9') {s=s+p*(ch^48);p*=0.1;ch=gc();}
}
s=f?-s:s;
}
template<class T,class ...A>
inline void read(T &s,A &...a){
read(s);read(a...);
}
};
using IO::read;
using IO::gs;
using IO::ps;
const int N=1e5+3;
const int N2=(N<<3);
const int M=(N<<3)+N*17;
const ll inf=1e18;
int n,m,s;
int head[N2],nxt[M];
struct Edge{
int u,v,w;
}to[M];
int Etot=-1;
inline void link(int u,int v,int w){
nxt[++Etot]=head[u];
head[u]=Etot;
to[Etot]={u,v,w};
}
int tot;
#define lc(x) (x<<1)
#define rc(x) (x<<1|1)
struct SegTree_in{
struct node{
int l,r,mid;
int id;
}t[N<<2];
inline void build(int x,int l,int r){
t[x].l=l;t[x].r=r;t[x].mid=(l+r)>>1;
if(l==r){
t[x].id=l;
return;
}else t[x].id=++tot;
build(lc(x),l,t[x].mid);
build(rc(x),t[x].mid+1,r);
link(t[x].id,t[lc(x)].id,0);
link(t[x].id,t[rc(x)].id,0);
}
inline void Link(int x,int u,int l,int r,int w){
if(l<=t[x].l and t[x].r<=r){
link(u,t[x].id,w);
return;
}
if(l<=t[x].mid) Link(lc(x),u,l,r,w);
if(t[x].mid+1<=r) Link(rc(x),u,l,r,w);
}
}in;
struct SegTree_ot{
struct node{
int l,r,mid;
int id;
}t[N<<2];
inline void build(int x,int l,int r){
t[x].l=l;t[x].r=r;t[x].mid=(l+r)>>1;
if(l==r){
t[x].id=l;
return;
}else t[x].id=++tot;
build(lc(x),l,t[x].mid);
build(rc(x),t[x].mid+1,r);
link(t[lc(x)].id,t[x].id,0);
link(t[rc(x)].id,t[x].id,0);
}
inline void Link(int x,int u,int l,int r,int w){
if(l<=t[x].l and t[x].r<=r){
link(t[x].id,u,w);
return;
}
if(l<=t[x].mid) Link(lc(x),u,l,r,w);
if(t[x].mid+1<=r) Link(rc(x),u,l,r,w);
}
}ot;
#undef lc
#undef rc
ll dis[N2];
bool vis[N2];
struct node{
int x;ll val;
inline friend bool operator < (node x,node y){
return x.val>y.val;
}
};
inline void Dijkstra(){
static std::priority_queue<node>q;
for(int i=1;i<=tot;++i){
dis[i]=inf;
}
dis[s]=0;
q.push({s,0});
while(!q.empty() ){
int u=q.top().x;q.pop();
if(vis[u]) continue;vis[u]=1;
for(int i=head[u];~i;i=nxt[i]){
int v=to[i].v,w=to[i].w;
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
if(!vis[v]) q.push({v,dis[v]});
}
}
}
}
int main(){
filein(a);fileot(a);
read(n,m,s);
tot=n;
memset(head,-1,sizeof(head) );
in.build(1,1,n);ot.build(1,1,n);
for(int i=1;i<=m;++i){
int op,u,v,l,r,w;
read(op);
if(op==1){
read(u,v,w);
link(u,v,w);
}
if(op==2){
read(u,l,r,w);
in.Link(1,u,l,r,w);
}
if(op==3){
read(u,l,r,w);
ot.Link(1,u,l,r,w);
}
}
Dijkstra();
for(int i=1;i<=n;++i){
printf("%lld ",dis[i]==inf?-1:dis[i]);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具