zoukankan      html  css  js  c++  java
  • 随机图

    建树

    老姚式建树(期望深度:log(n))

    #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	srand(time(0));srand(rand());
    	int n=100;
    	printf("%d
    ",n);
    	for(int i=2;i<=n;i++){
    		printf("%d %d
    ",i,rand()%(i-1)+1);
    	}
    }
    
    

    skyh式建树(期望深度:sqrt(n))

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=150;
    int fa[maxn];
    int find_root(int x){return fa[x]==x?x:fa[x]=find_root(fa[x]);}
    int main(){
    	srand(time(0));srand(rand());
    	int n=100,cnt=n;
    	printf("%d
    ",n);
    	for(int i=1;i<=n;i++)fa[i]=i;
    	int tot=0;
    	while(cnt!=1){
    		int x=rand()%n+1,y=rand()%n+1;
    		if(find_root(x)==find_root(y))continue;
    		fa[find_root(x)]=find_root(y);
    		printf("%d %d
    ",x,y);cnt--;
    	}
    }
    

    建图

    联通图,建树连边

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=150;
    int fa[maxn];
    int find_root(int x){return fa[x]==x?x:fa[x]=find_root(fa[x]);}
    int main(){
    	srand(time(0));srand(rand());
    	int n=100,m=300,cnt=n;
    	printf("%d %d
    ",n,m);
    	for(int i=1;i<=n;i++)fa[i]=i;
    	while(cnt!=1){
    		int x=rand()%n+1,y=rand()%n+1;
    		if(find_root(x)==find_root(y))continue;
    		fa[find_root(x)]=find_root(y);
    		printf("%d %d
    ",x,y);cnt--;
    	}
    	for(int i=1;i<=m-n+1;i++){
    		int x=rand()%n+1,y=rand()%n+1;
    		while(x==y)x=rand()%n+1,y=rand()%n+1;
    		printf("%d %d
    ",x,y);
    	}
    }
    

    DAG图

    #include<bits/stdc++.h>
    #define build HASH(int _nxt,int _x,int _y){nxt=_nxt,x=_x,y=_y;}
    using namespace std;
    const int maxn=1e5+10,mod=59999;
    int n=100,m=150;//调整
    int ver[maxn<<1],nxt[maxn<<1],head[maxn],tot,cntt=n;
    int dfn[maxn],low[maxn],fa[maxn],sta[maxn],belong[maxn],top,cnt,num,CNT;
    bool ins[maxn];
    vector<int>scc[maxn];
    void add(int x,int y){ver[++tot]=y,nxt[tot]=head[x],head[x]=tot;}
    int find_root(int x){return fa[x]==x?x:fa[x]=find_root(fa[x]);}
    void Build_Map(){
    	while(cntt!=1){
    		int x=rand()%n+1,y=rand()%n+1;
    		if(find_root(x)==find_root(y))continue;
    		fa[find_root(x)]=find_root(y);
    		cntt--;
    		if((rand()%2)&1)add(x,y);
    		else add(y,x);
    	}
    	for(int i=1;i<=m-n+1;i++){
    		int x=rand()%n+1,y=rand()%n+1;
    		while(x==y)x=rand()%n+1,y=rand()%n+1;
    		if((rand()%2)&1)add(x,y);
    		else add(y,x);
    	}
    }
    void tarjan(int x){
    	dfn[x]=low[x]=++num;
    	sta[++top]=x,ins[x]=1;
    	for(int i=head[x];i;i=nxt[i])
    		if(!dfn[ver[i]]){
    			tarjan(ver[i]);
    			low[x]=min(low[x],low[ver[i]]);
    		}
    		else if(ins[ver[i]])low[x]=min(low[x],dfn[ver[i]]);
    	if(dfn[x]==low[x]){
    		cnt++;int y;
    		do{
    			y=sta[top--],ins[y]=0;
    			belong[y]=cnt,scc[cnt].push_back(y);
    		}while(x!=y);
    	}
    }
    struct EDGE{
    	int x,y;
    	EDGE(){}
    	EDGE(int _x,int _y){x=_x,y=_y;}
    }edge[maxn<<1];
    int head_ha[maxn],hac;
    struct HASH{int nxt,x,y;HASH(){};build;}Hash[maxn<<1];
    void hash_add(int x,int y){
    	int ha=(x*maxn+y)%mod;
    	Hash[++hac]=HASH(head_ha[ha],x,y);
    	head_ha[ha]=hac;
    }
    bool find(int x,int y){
    	int ha=(x*maxn+y)%mod;
    	for(int i=head_ha[ha];i;i=Hash[i].nxt)
    		if(Hash[i].x==x&&Hash[i].y==y)
    			return 1;
    	return 0;
    }
    int main(){
    	srand(time(0));srand(rand());
    	for(int i=1;i<=n;i++)fa[i]=i;
    	Build_Map();
    	for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
    	for(int x=1;x<=n;x++){
    		for(int i=head[x];i;i=nxt[i]){
    			int y=ver[i];
    			if(belong[x]==belong[y])continue;
    			if(find(belong[x],belong[y])==0)hash_add(belong[x],belong[y]),edge[++CNT]=EDGE(belong[x],belong[y]);
    		}
    	}
    	printf("%d %d
    ",cnt,CNT);
    	for(int i=1;i<=CNT;i++)printf("%d %d
    ",edge[i].x,edge[i].y);
    }
    
    
    

    洛谷

    import random
    list_like = lambda data: isinstance(data, tuple) or isinstance(data, list)
    class Edge:
        def __init__(self, u, v, w):
            self.start, self.end, self.weight = u, v, w
        def __str__(self):
            return "{} {} {}".format(self.start, self.end, self.weight)
        @staticmethod
        def unweighted_edge(edge):
            return '{} {}'.format(edge.start,edge.end)
    class Graph:
        def __init__(self, point_count, directed=False):
            self.directed, self.edges = directed, [[] for i in range(point_count + 1)]
        def to_str(self, **kwargs):
            shuffle = kwargs.get("shuffle", False)
            weighted = kwargs.get("weighted", False)
            output = str if weighted else Edge.unweighted_edge
            buf = []
            if shuffle:
                new_node_id = [i for i in range(1, len(self.edges))]
                random.shuffle(new_node_id)
                new_node_id = [0] + new_node_id
                edge_buf = []
                for edge in self.iterate_edges():
                    edge_buf.append(Edge(new_node_id[edge.start], new_node_id[edge.end], edge.weight))
                random.shuffle(edge_buf)
                for edge in edge_buf:
                    if not self.directed and random.randint(0, 1) == 0:
                        (edge.start, edge.end) = (edge.end, edge.start)
                    buf.append(output(edge))
            else:
                for edge in self.iterate_edges():
                    buf.append(output(edge))
            return "
    ".join(buf)
        def print(self, **kwargs):
            print(self.to_str(**kwargs))
        def iterate_edges(self):
            for node in self.edges:
                for edge in node:
                    if edge.end >= edge.start or self.directed:
                        yield edge
        def __add_edge(self, x, y, w):
            self.edges[x].append(Edge(x, y, w))
        def add_edge(self, x, y, **kwargs):
            weight = kwargs.get("weight", 1)
            self.__add_edge(x, y, weight)
            if not self.directed and x != y:
                self.__add_edge(y, x, weight)
        @staticmethod
        def chain(point_count, **kwargs):
            return Graph.tree(point_count, 1, 0, **kwargs)
        @staticmethod
        def flower(point_count, **kwargs):
            return Graph.tree(point_count, 0, 1, **kwargs)
        @staticmethod
        def tree(point_count, chain=0, flower=0, **kwargs):
            directed = kwargs.get("directed", False)
            weight_limit = kwargs.get("weight_limit", (1, 1))
            if not list_like(weight_limit):
                weight_limit = (1, weight_limit)
            weight_gen = kwargs.get("weight_gen", lambda: random.randint(weight_limit[0], weight_limit[1]))
            if not 0 <= chain <= 1 or not 0 <= flower <= 1:
                raise Exception("chain and flower must be between 0 and 1")
            if chain + flower > 1:
                raise Exception("chain plus flower must be smaller than 1")
            graph = Graph(point_count, directed)
            chain_count = int((point_count - 1) * chain)
            flower_count = int((point_count - 1) * flower)
            if chain_count > point_count - 1:
                chain_count = point_count - 1
            if chain_count + flower_count > point_count - 1:
                flower_count = point_count - 1 - chain_count
            random_count = point_count - 1 - chain_count - flower_count
            for i in range(2, chain_count + 2):
                graph.add_edge(i - 1, i, weight=weight_gen())
            for i in range(chain_count + 2, chain_count + flower_count + 2):
                graph.add_edge(1, i, weight=weight_gen())
            for i in range(point_count - random_count + 1, point_count + 1):
                u = random.randrange(1, i)
                graph.add_edge(u, i, weight=weight_gen())
            return graph
        @staticmethod
        def binary_tree(point_count, left=0, right=0, **kwargs):
            directed = kwargs.get("directed", False)
            weight_limit = kwargs.get("weight_limit", (1, 1))
            if not list_like(weight_limit):
                weight_limit = (1, weight_limit)
            weight_gen = kwargs.get(
                "weight_gen", lambda: random.randint(
                    weight_limit[0], weight_limit[1]))
            if not 0 <= left <= 1 or not 0 <= right <= 1:
                raise Exception("left and right must be between 0 and 1")
            if left + right > 1:
                raise Exception("left plus right must be smaller than 1")
            can_left = set([1])
            can_right = set([1])
            graph = Graph(point_count, directed)
            for i in range(2, point_count + 1):
                edge_pos = random.random()
                node = 0
                # Left
                if edge_pos < left or left + right < edge_pos <= (1.0 - left - right) / 2:
                    node = random.choice(tuple(can_left))
                    can_left.remove(node)
                # Right
                elif left <= edge_pos <= left + right or (1.0 - left - right) / 2 < edge_pos < 1:
                    node = random.choice(tuple(can_right))
                    can_right.remove(node)
                graph.add_edge(node, i, weight=weight_gen())
                can_left.add(i)
                can_right.add(i)
            return graph
    
        @staticmethod
        def graph(point_count, edge_count, **kwargs):
            directed = kwargs.get("directed", False)
            self_loop = kwargs.get("self_loop", False)
            repeated_edges = kwargs.get("repeated_edges", False)
            weight_limit = kwargs.get("weight_limit", (1, 1))
            if not list_like(weight_limit):
                weight_limit = (1, weight_limit)
            weight_gen = kwargs.get(
                "weight_gen", lambda: random.randint(
                    weight_limit[0], weight_limit[1]))
            graph = Graph(point_count, directed)
            used_edges = set()
            i = 0
            while i < edge_count:
                u = random.randint(1, point_count)
                v = random.randint(1, point_count)
    
                if (not self_loop and u == v) or (not repeated_edges and (u, v) in  used_edges):
                    # Then we generate a new pair of nodes
                    continue
    
                graph.add_edge(u, v, weight=weight_gen())
    
                if not repeated_edges:
                    used_edges.add((u, v))
                    if not directed:
                        used_edges.add((v, u))
    
                i += 1
            return graph
    
        @staticmethod
        def DAG(point_count, edge_count, **kwargs):
            if edge_count < point_count - 1:
                raise Exception("the number of edges of connected graph must more than the number of nodes - 1")
    
            self_loop = kwargs.get("self_loop", False) # DAG default has no loop
            repeated_edges = kwargs.get("repeated_edges", True)
            loop = kwargs.get("loop", False)
            weight_limit = kwargs.get("weight_limit", (1, 1))
            if not list_like(weight_limit):
                weight_limit = (1, weight_limit)
            weight_gen = kwargs.get(
                "weight_gen", lambda: random.randint(
                    weight_limit[0], weight_limit[1]))
            
            used_edges = set()
            edge_buf = list(Graph.tree(point_count, weight_gen=weight_gen).iterate_edges())
            graph = Graph(point_count, directed=True)
    
            for edge in edge_buf:
                if loop and random.randint(1, 2) == 1:
                    edge.start, edge.end = edge.end, edge.start
                graph.add_edge(edge.start, edge.end, weight=edge.weight)
                    
                if not repeated_edges:
                    used_edges.add((edge.start, edge.end))
            
            i = point_count - 1
            while i < edge_count:
                u = random.randint(1, point_count)
                v = random.randint(1, point_count)
    
                if not loop and u > v:
                    u, v = v, u
    
                if (not self_loop and u == v) or (not repeated_edges and (u, v) in  used_edges):
                    # Then we generate a new pair of nodes
                    continue
    
                graph.add_edge(u, v, weight=weight_gen())
    
                if not repeated_edges:
                    used_edges.add((u, v))
    
                i += 1
    
            return graph
    
        @staticmethod
        def UDAG(point_count, edge_count, **kwargs):
            if edge_count < point_count - 1: 
                raise Exception("the number of edges of connected graph must more than the number of nodes - 1")
    
            self_loop = kwargs.get("self_loop", True)
            repeated_edges = kwargs.get("repeated_edges", True)
            weight_limit = kwargs.get("weight_limit", (1, 1))
            if not list_like(weight_limit):
                weight_limit = (1, weight_limit)
            weight_gen = kwargs.get(
                "weight_gen", lambda: random.randint(
                    weight_limit[0], weight_limit[1]))
            
            used_edges = set()
            graph = Graph.tree(point_count, weight_gen=weight_gen, directed=False)
    
            for edge in graph.iterate_edges():
                if not repeated_edges:
                    used_edges.add((edge.start, edge.end))
                    used_edges.add((edge.end, edge.start))
            
            i = point_count - 1
            while i < edge_count:
                u = random.randint(1, point_count)
                v = random.randint(1, point_count)
    
                if (not self_loop and u == v) or (not repeated_edges and (u, v) in  used_edges):
                    # Then we generate a new pair of nodes
                    continue
    
                graph.add_edge(u, v, weight=weight_gen())
    
                if not repeated_edges:
                    used_edges.add((u, v))
                    used_edges.add((v, u))
    
                i += 1
    
            return graph
    
        @staticmethod
        def hack_spfa(point_count, **kwargs):
            directed = kwargs.get("directed", False)
            extraedg = kwargs.get("extra_edge", 2)
            weight_limit = kwargs.get("weight_limit", (1, 1))
            if not list_like(weight_limit):
                weight_limit = (1, weight_limit)
            weight_gen = kwargs.get(
                "weight_gen", lambda: random.randint(
                    weight_limit[0], weight_limit[1]))
    
            point_to_skip = point_count + 3
            graph = Graph(point_count, directed)
            if point_count % 2 == 1:
                point_to_skip = point_count / 2 + 1
            half = int(point_count / 2)
    
            for i in range(1, half):
                (x, y) = (i, i + 1)
                graph.add_edge(x + (x >= point_to_skip), y +
                               (y >= point_to_skip), weight=weight_gen())
                (x, y) = (i + half, i + half + 1)
                graph.add_edge(x + (x >= point_to_skip), y +
                               (y >= point_to_skip), weight=weight_gen())
            for i in range(1, half + 1):
                (x, y) = (i, i + half)
                graph.add_edge(x + (x >= point_to_skip), y +
                               (y >= point_to_skip), weight=weight_gen())
    
            for i in range(extraedg):
                u = random.randint(1, point_count)
                v = random.randint(1, point_count)
                graph.add_edge(u, v, weight=weight_gen())
    
            return graph
    n = 10
    m = 20
    print(n, m)
    Graph.graph(n, m, weight_limit=5).print(weighted=True)
    
    
    
    
  • 相关阅读:
    如何解除任务管理器被禁用
    一、JavaScript概述
    001_html基本结构
    postman常见问题记录
    fidder工具使用
    SonarQube工具使用问题汇总
    业余书籍读后感
    jmater常见问题处理
    测试知识记录(更新中)
    HTTP协议
  • 原文地址:https://www.cnblogs.com/soda-ma/p/13886165.html
Copyright © 2011-2022 走看看