【模板】链式前向星存图 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;
}
posted @ 2022-11-06 19:17  caijianhong  阅读(36)  评论(0编辑  收藏  举报