图
基本概念
图由顶点的非空有序集合V和边的集合E组成,记为G=(V,E)。每条边就是一个顶点的偶对,所以E也就是V上的关系。图G中的顶点集合可以用G.V或者V(G)表示;类似地可用G.E或E(G)表示图G中边的集合。
若图中的每条边都是有方向的,则称为有向图。有序对通常用尖括号表示,如<v1,v2>表示一条有向边,其中v1是边的始点,v2是边的终点。
若图中每条边都是无方向的,则称为无向图。无序对通常用圆括号表示,(v1,v2)和(v2,v1)表示同一条有向边。
完全图
有n(n-1) 条边的有向图称为有向完全图,有n(n-1)/2条边的无向图称为无向完全图。
关联与邻接
若<v1,v2>是一条有向边,则称顶点v1邻接v2或顶点v2邻接于v1,边<v1,v2>与顶点v1,v2相关联。若(v1,v2)是一条无向边,则v1,v2是相邻结点,(v1,v2)是与顶点v1和v2相关联的点。
度、入度和出度
与顶点v相关联的边数称为顶点的度,记为D(v)。若G是一个有向图,则以顶点v为终点的边的数目称为v的入度,记为ID(v);以v为始点的边的数目称为v的出度,记为OD(v),有向图中顶点v的度为其入度与出度之和,即D(v) = ID(v) + OD(v)。
子图
设有图G = (V,E) 和 G’ =(V’,E’) ,如果V’是V的子集,E’是E的子集,则称G’是G的子图。
根与有根图
有向图中,若存在一顶点v,从该顶点有路径可以到图中其他所有顶点,则称此有向图为有根图,v称为图的根,显然有根图中的根可能是不唯一的。
邻接表表示法
图的邻接表表示法也包括两部分;顺序存储的顶点表和每个顶点相关联的链式存储的边表。
struct edgenode;
typedef struct edgenode * pedgenode;
typedef struct edgenode * Edgelist;
struct edgenode{
int endvex;
Adjtype weight;
pedgenode nextedge;
};
typedef struct {
Vextype vertex;
Edgelist edgelist;
}Vexnode;
typedef struct {
Vexnode vexs[VN];
}Graphlist;
洛谷 p3916 图的遍历
题目描述
给出 N 个点,M 条边的有向图,对于每个点 v,求 A(v) 表示从点 v 出发,能到达的编号最大的点。
输入格式
第 1 行 2 个整数 N,M,表示点数和边数。
接下来 M 行,每行 2 个整数 Ui,Vi,表示边 (Ui,Vi)。点用 1,2,…,N 编号。
输出格式
一行 N 个整数 A(1),A(2),…,A(N)。
输入输出样例
输入
4 3
1 2
2 4
4 3
输出
4 4 3 4
说明/提示
对于 60% 的数据,1≤N,M≤103。
对于 100% 的数据,1≤N,M≤105。
图的遍历
#include<bits/stdc++.h>
using namespace std;
#define B b[d][i]
int n, m, u, v, a[100001];
vector<int>b[100001];
void fun(int d, int z) {
if (a[d] >= z)return;
a[d] = z;
for (int i(0), s(b[d].size()); i < s; ++i)fun(B, z);
}
int main() {
cin >> n >> m;
while (m--)cin >> u >> v, b[v].push_back(u);
for (int i(n); i >= 1; --i)
fun(i, i);
for(int i(1); i <= n; ++i)
cout << a[i] << ' ';
return 0;
}
部分内容借鉴了一些大佬的博客。