【模板】链式前向星存图 graph
posted on 2021-09-04 20:03:43 | under 模板 | source
点击查看代码
template <int N, int M, class T>
struct graph {
int head[N + 10], nxt[M << 1], cnt;
struct edge {
int u, v;
T w;
} e[M << 1];
graph() { memset(head, cnt = 0, sizeof head); }
edge& operator[](int i) { return e[i]; }
void add(int u, int v, T w = 0) {
e[++cnt] = {u, v, w}, nxt[cnt] = head[u], head[u] = cnt;
}
void link(int u, int v, T w = 0) { add(u, v, w), add(v, u, w); }
};
template<int N,int M,class T=int> struct graph{
int head[N+10],nxt[M*2+10],cnt;
struct edge{
int u,v;T w;
edge(int u=0,int v=0,T w=0):u(u),v(v),w(w){}
} e[M*2+10];
graph(){memset(head,cnt=0,sizeof head);}
edge&operator[](int i){return e[i];}
void add(int u,int v,T w=0){e[++cnt]=edge(u,v,w),nxt[cnt]=head[u],head[u]=cnt;}
void link(int u,int v,T w=0){add(u,v,w),add(v,u,w);}
};
ext:
template<int N,int M,class T=int> struct graph{
int head[N+10],nxt[M*2+10],cnt;
struct edge{
int u,v;T w;
edge(int u=0,int v=0,T w=0):u(u),v(v),w(w){}
bool operator<(edge b)const{if(u!=b.u) return u<b.u;if(v!=b.v) return v<b.v;return w<b.w;}
bool operator==(edge b){return u==b.u&&v==b.v&&w==b.w;}
} e[M*2+10];
graph(){memset(head,cnt=0,sizeof head);}
edge operator[](int i){return e[i];}
void add(int u,int v,T w=0){e[++cnt]=edge(u,v,w),nxt[cnt]=head[u],head[u]=cnt;}
void link(int u,int v,T w=0){add(u,v,w),add(v,u,w);}
void vnique(){
sort(e+1,e+cnt+1);
int m=unique(e+1,e+cnt+1)-e-1;
memset(head,cnt=0,sizeof head);
for(int i=1;i<=m;i++){
if(e[i].u!=e[i].v) add(e[i].u,e[i].v,e[i].w);
}
}
template<class Dsu> void reset(Dsu s){
int m=cnt;
memset(head,cnt=0,sizeof head);
for(int i=1;i<=m;i++){
if(!s.query(e[i].u,e[i].v)) add(s.find(e[i].u),s.find(e[i].v),e[i].w);
}
}
};
清空:
template<int N,int M,class T=int> struct graph{
int head[N+10],nxt[M*2+10],cnt;
int vis[N+10],tag;
struct edge{
int u,v;T w;
edge(int u=0,int v=0,T w=0):u(u),v(v),w(w){}
} e[M*2+10];
graph(){memset(head,cnt=0,sizeof head),memset(vis,tag=0,sizeof vis);}
edge&operator[](int i){return e[i];}
void add(int u,int v,T w=0){
if(vis[u]!=tag) vis[u]=tag,head[u]=0;
e[++cnt]=edge(u,v,w),nxt[cnt]=head[u],head[u]=cnt;
}
void link(int u,int v,T w=0){add(u,v,w),add(v,u,w);}
};
sample:
graph<100010,200010,int> g;//一张有 1e5 个点,2e5 条无向带 int 权边的图
graph<100010,100010> t;//一棵 1e5 个点的树,无权
g.add(1,2,-114514);//加入 1->2 的有向边,其权值为 -114514
t.link(2,3);//树中有 2<->3 的无向边
for(int i=g.head[u];i;i=g.nxt[i]){
int v=g[i].v,w=g[i].w;
}
本文来自博客园,作者:caijianhong,转载请注明原文链接:https://www.cnblogs.com/caijianhong/p/template-graph.html