图论基础

对于图的遍历,可以用邻接表邻接矩阵来实现。
因为图不同于树结构,图是存在非连续的。所以图无法运用链式结构。
图又有4种情况,分别对应有无权值,有无方向

  • 有权无向图
  • 有权有向图
  • 无权无向图
  • 无权有向图

图的表示方法

邻接表和邻接矩阵

运用邻接表:

int u,v;
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);

因为图的各个区域的点的个数不同,所有无法用统一的二维数组,应该用向量数组

运用邻接矩阵:

int u,v;
scanf("%d%d",&u,&v);
g[u][v]=1;
g[u][v]=1;

两个点如果相互连接的话,其邻接矩阵的值就是1
在无向图里要两个都进行赋值1,而在有向图里就只需要赋值一次
所有在无向图里浪费了一半的空间

连通分量模型---求无向图组成的图的个数

对图进行遍历,求有几个区域
思路:
构建向量数组和颜色数组
向量数组用于储存关系,每个向量的头结点代表头,之后的表示与头结点相互连接的边
颜色数组用于存储颜色数值,不同的区域具有不同的颜色,相互连接,可以传递的结点具有相同的颜色数值

无向图,所以a对b,b也对a
建立向量数组,存储后,对颜色初始化
开始对n个结点查询,只要遇到color为初始值的结点就进行该结点的dfs
在dfs中运用栈,将该结点的边的结点进行压入栈且把这些结点的颜色值和其相连接的结点的颜色值变成父结点的颜色值

利用邻接表遍历图

>在函数的形参中适用后自增++的话,要等到函数结束后才执行
>也就是本题第一个颜色输出为1而不是2的原因

#include <iostream>
#include <cstdio>
#include <vector>
#include <stack>
using namespace std;
static const int MAX = 1005;
static const int NIL = -1;

int n,m;
vector<int> g[MAX];//1005个顶点的图的邻接表
int color[MAX];

void dfs(int r,int c){
    stack<int>s;
    s.push(r);

    color[r]=c;//相互连接的结点拥有同样的颜色;

    while(!s.empty()){
        //u作为待处理的父连接点
        int u=s.top();
        s.pop();

        for(int i=0;i<g[u].size();i++){
            //v是待处理的子连接点
            int v=g[u][i];
            if(color[v]==NIL){
                color[v]=c;
                s.push(v);
            }
        }
    }
}


void assignColor(){
    int id=1;
    //初始化
    for(int i=0;i<n;i++){
        color[i]=NIL;
    }
    for(int u=0;u<n;u++){
        if(color[u]==NIL){
            dfs(u,id++);
        }
    }

}
int main(){
    //n个结点,m条边
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++){
        int u,v;
        scanf("%d%d",&u,&v);

        g[u].push_back(v);
        g[v].push_back(u);
    }

    assignColor();

    //输出所有颜色
    for(int i=0;i<n;i++){
        printf("%d",color[i]);
    }

    return 0;
} 

强连通分量---有向图中所有点都可以到达的

  • 在有向图G中,如果两个点可以互相到达,则称这两个点强连通
  • 如果G中任意两个点可以互相到达,则称G是强连通图

转载于:https://www.cnblogs.com/Emcikem/p/11354225.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值