zoukankan      html  css  js  c++  java
  • 20200912 day7 图论复习(一)

    1 图论基础

    1. 有向图(G)中,(V)表示顶点,(E)表示边。
    2. 无向图中不允许存在自环。
    3. 无向图中,定点的度是指关联于该顶点的边的数目。
    4. 有向图中,顶点的出度是离开该定点的边的数目。出度是指进入该顶点的边的数目。度是入度与出度之和。

    1.1 邻接矩阵

    (|E|=n)的邻接矩阵是一个$n imes n $的矩阵。无权图中用1表示邻接,0表示不邻接。
    带权图中数字表示边的权重,无穷(有时用0)表示两点不邻接。
    无向图的邻接矩阵是关于对角线对称的。

    1.2 链式前向星

    空间复杂度(O(E))

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #define N 5005
    #define M 20005
    using namespace std;
    int cnt=0,head[N]; 
    struct node{
    	int to,next,val;
    }edge[N];
    void add(int x,int y,int val1){
    	edge[++cnt].next=head[x];
    	edge[cnt].to=y;
    	edge[cnt].val=val1;
    	head[x]=cnt;
    	
    }
    int main(){
    	
    }
    memset(head,-1,sizeof(head));
    for(int i=head[x];i!=-1;i=edge[i].next){
    	int to1=edge[i].to;
    	//do something
    }
    

    2 最小生成树

    2.0 并查集

    模板 LGP3367

    题目描述

    现在有一个并查集,你需要完成合并和查询操作。

    输入格式

    第一行包含两个整数(N)(M),表示共有(N)个元素和(M)个操作。
    接下来(M)行,每行包含三个整数(Z_i)(X_i)(Y_i)
    (Z_i=1)时,将(X_i)(Y_i)所在的集合合并
    (Z_i=2)时,输出(X_i)(Y_i)是否在同一集合内,是的话输出(Y);否则话输出(N)

    输出格式

    如上,对于每一个(Z_i=2)的操作,都有一行输出,每行包含一个大写字母,为(Y)或者(N)

    输入输出样例

    输入

    4 7
    2 1 2
    1 1 2
    2 1 2
    1 3 4
    2 1 4
    1 2 3
    2 1 4
    

    输出

    N
    Y
    N
    Y
    

    数据规模

    对于(30\%)的数据,(Nleq 10)(Mleq 20)
    对于(70\%)的数据,(Nleq 100)(Mleq 1000)
    对于(100\%)的数据,(Nleq 10000)(Mleq 200000)

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define N 50005
    using namespace std;
    //get together jihe
    int fa[N];
    int n; 
    void init(){
    	for(int i=1;i<=n;i++) fa[i]=i;
    }
    int find(int x){
    	return x==fa[x]?x:fa[x]=find(fa[x]);
    }
    void uni(int x,int y){
    	fa[find(x)]=find(y);
    }
    int main(){
    	int n,m;
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++) fa[i]=i;
    //init();
    	while(m--){
    		int a=0,b=0,c=0;
    		scanf("%d%d%d",&a,&b,&c);
    		if(a==1){
    			fa[find(b)]=find(c);
    		}
    		else if(a==2){
    			if(find(b)==find(c)){
    				printf("Y
    ");
    			}
    			else{
    				printf("N
    ");
    			}
    		}
    	}
    	return 0;
    }
    

    2.1 Kruskal

    //Kraskul
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #define N 5005
    #define M 200005
    using namespace std;
    int cnt=0,head[M],fa[M];//fa维护点的连通性 
    struct node{
    	int to,next,val;
    }edge[M];
    int find(int x){
    	return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    bool cmp(node x,node y){
    	return x.val<y.val;
    }
    void add(int x,int y,int val1){
    	edge[++cnt].next=head[x];
    	edge[cnt].to=y;
    	edge[cnt].val=val1;
    	head[x]=cnt;
    }
    int tgn,tgto,ans;
    int main(){
    	memset(head,-1,sizeof(head));
    	int n,m;
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++){
    		fa[i]=i;
    	} 
    	for(int i=1;i<=m;i++){
    		scanf("%d%d%d",&edge[i].next,&edge[i].to,&edge[i].val);
    	}
    	//kruskal
    	sort(edge+1,edge+m+1,cmp);
    	for(int i=1;i<=m;i++){
    		tgn=find(edge[i].next);
    		tgto=find(edge[i].to);
    		if(tgn==tgto){
    			continue;
    		}
    		//若已经联通,则不需要这一条边
    		ans+=edge[i].val;
    		 //边权记录答案
    		fa[tgto]=tgn; //联通tgto和tgn 
    		if(++cnt==n-1){
    			break;
    		}
    		//边为点数减一时停止 
    	}
    	if(ans!=0) printf("%d",ans);
    	else printf("orz");
    	return 0;
    }
    /* 
    for(int i=head[x];i!=-1;i=edge[i].next){
    	int to1=edge[i].to;
    	//do something
    }
    */
    

    2.2 Prim

    复杂度(O(V^2)),适用于稠密图
    prim详解

    3 最短路

    3.1 单源最短路径

    (弱化版)

    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #define N  20005
    #define edge e
    using namespace std;
    struct node{
    	int to,next,val;
    }e[1000001];
    int head[N],num;
    void add(int x,int y,int val1){
    	e[++num].next=head[x];
    	e[num].to=y;
    	e[num].val=val1;
    	head[x]=num;
    }
    bool vis[20005]={0};
    long long dis[20005];
    int n,m,s;
    int a,b,c;
    #define K 2147483647
    int main(){
    	scanf("%d%d%d",&n,&m,&s);
    	for(int i=1;i<=n;i++) dis[i]=K;
    	for(int i=1;i<=m;i++){
    		scanf("%d%d%d",&a,&b,&c);
    		add(a,b,c);
    	}
    	int curr=s;
    	dis[s]=0;
    	long long minn;
    	while(!vis[curr]){
    		vis[curr]=1;
    		for(int i=head[curr];i!=0;i=edge[i].next){
    			if(!vis[edge[i].to]&&dis[edge[i].to]>dis[curr]+edge[i].val){
    				dis[edge[i].to]=dis[curr]+edge[i].val;//更新每个点 
    			}
    		}
    		minn=K;
    		for(int i=1;i<=n;i++){
    			if(!vis[i]&&minn>dis[i]){
    				minn=dis[i];
    				curr=i;
    			}
    		}
    
    	}
    	for(int i=1;i<=n;i++) printf("%lld ",dis[i]);
    	return 0;
    } 
    
    要做就做南波万
  • 相关阅读:
    [python]如何理解uiautomator里面的 instance 及使用场景
    [python]如何理解uiautomator里面的 right,left,up,down 及使用场景
    [python] try......except.....finally
    [python]python官方原版编码规范路径
    [python]pip 版本9.0.1升级到10.0.1故障解决办法
    [python]如何理解uiautomator里面的 child, child_by_text, sibling,及使用场景
    [python]关于在python中模块导入问题追加总结
    [Eclipse]如何往eclipse中导入单个python文件,其它类型代码文件也可以参照该方法
    [Eclipse]在重命令文件名时,提示编码格式有问题导致修改失败,需要设置如下几个默认编码为UTF-8
    [MySQL]在安装windows版MySQL时遇到过如下问题Error Nr.1045和Error.Nr.2003,相应解决办法如下
  • 原文地址:https://www.cnblogs.com/liuziwen0224/p/20200912day7-001.html
Copyright © 2011-2022 走看看