邻接矩阵

题外话

老师这回又叫我们来写博客了,写一写邻接矩阵。
注意:本博客仅讨论无向无权图
想必上一个博客已经让大家了解了图的基本知识了
没来得及看的在csdn上随便搜一篇来看因为我都是摘录百度百科的
比如这篇博客图的定义、读入与储存_dyx916_的博客-CSDN博客
咳咳,接下来正式进入正题:

邻接矩阵

首先看一下定义:
以下摘自百度百科

邻接矩阵(Adjacency Matrix)是表示顶点之间相邻关系的矩阵。设 G = ( V , E ) G=(V,E) G=(V,E)是一个图,其中 V = v 1 , v 2 , … , v n V={v1,v2,…,vn} V=v1,v2,,vn [1] 。 G G G的邻接矩阵是一个具有下列性质的 n n n阶方阵:
①对无向图而言,邻接矩阵一定是对称的,而且主对角线一定为零(在此仅讨论无向简单图),副对角线不一定为 0 0 0,有向图则不一定如此。
②在无向图中,任一顶点i的度为第 i i i列(或第 i i i行)所有非零元素的个数,在有向图中顶点 i i i的出度为第i行所有非零元素的个数,而入度为第 i i i列所有非零元素的个数。
③用邻接矩阵法表示图共需要 n 2 n^2 n2个空间,由于无向图的邻接矩阵一定具有对称关系,所以扣除对角线为零外,仅需要存储上三角形或下三角形的数据即可,因此仅需要 n ( n − 1 ) / 2 n(n-1)/2 nn1/2个空间。

咋一看,好像好深奥啊,我看不懂。
别急,举个如何把邻接矩阵画出来的例子就好理解了:
以这张图G1为例:
在这里插入图片描述

首先呢因为这是个无向无权图,所以它的邻接矩阵里面只有0和1,
让后呢把两个连通的的节点在邻接矩阵 V V V里设为 1 1 1,不能连通的设为 0 0 0
如,节点1和节点2能联通,所以把 V ( 1 , 2 ) V(1,2) V(1,2)设为1
这样一顿操作后原本这样的邻接矩阵

01234567
1
2
3
4
5
6
7

变成了这样的

01234567
10110000
21001000
31000011
40100000
50000010
60010100
70010000

现在,你应该理解透彻了邻接矩阵的制作方法了,吧
接下来来实战演练一下:

示例讲解

首先来看看题面题目传送门

1083: 自制-对立游戏邻接矩阵

题目描述

鸡哥(又名“sin雪梨鸡”)带领一群同学在玩对立游戏,简单来说就是每个人都要找寻自己对立的对象,找完后每个人要在5秒内记住场上的局势,5秒后谁能最完整地复述出来谁就赢了,最后一名要经历胜者惨无人道的惩罚(指午饭被拿走一些菜)鸡哥虽是这场游戏的领导者,但是他自己也不敢保证自己必赢,这时小陈老师走了出来,对他说:“我可以帮你观察局势,但我不知道如何表示我观察到的,如果你有可以表示的方法,我会帮你观察表示并投影在天花板上,到时候你直接看就行了,别人只会认为这是普通的投影”
鸡哥顿感心动,突然想到了前几天学过的邻接矩阵,鸡哥让老师用邻接矩阵来把局势投影到天花板上。小陈老师心想:“嘶,邻接矩阵我也没掌握熟练啊”,于是他准备让你帮帮他,你的程序必须在0.3秒内运行完,因为小陈老师摆投影要0.7秒,又因为小陈老师的电脑内存很小,所以你的程序必须在7MiB内运行完成

输入

第1行: 一个整数N和一个整数M, 表示N个同学和M个对立行为 第2~M+1行: 输入两个整数i和j 表示i同学正在对立j同学

输出

N*N的邻接矩阵,其中两点间没联系的用0表示,有对立关系的点用1表示,点相重叠用2表示

样例输入

4 4
1 2
2 4
3 1
3 4

样例输出

2 1 0 0
0 2 0 1
1 0 2 1
0 0 0 2

提示

每个同学的编号依次为1~N
对于57%的数据:N,M<=50 对于29%的数据:N,M<=500 对于14%的数据:N<=10³,M<=10⁵
(后话:作者测试节点用了两个小时才搞完,来做一下吧QAQ)

首先先导入定义一堆东西:

#include<bits/stdc++.h>
using namespace std;
int a[1010][1010];//定义输出数组
int f,t;//定义输入的from和to

然后写主函数:

int main(){
    int n,m; cin>>n>>m;//输入次数
    for(int i=1;i<=m;i++){
        cin>>f>>t;//输入这条边的from和to
        a[f][t]=1;//将这条边在邻接矩阵中设为1
    }
    for(int i=1;i<=n;i++){
        a[i][i]=2;//把对角线的设为2,因为对角线的一定是重叠的
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cout<<a[f][t]<<" ";//输出
        }
        cout<<endl;//输出换行
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值