图总结

1.思维导图

2.重要概念的笔记(不求多但求精)

建图

1.邻接矩阵
//根据value节点值返回节点位置,没找到则返回-1
int LocateVex(MyGraph &G, VexType value)
{
	for (int i = 0; i < G.vexNum; i++)
	{
		if (value == G.vexs[i])
			return i;
	}
	return -1;
}

void CreateGraphFromConsole(MyGraph &G, int vexNum, int arcNum)
{
	G.vexNum = vexNum;
	G.arcNum = arcNum;
	int x,y;
	for (int i = 0; i < vexNum; i++)
	{
		for (int j = 0; j < vexNum; j++)
		{
			G.edges[i][j] = 0;//初始化
		}
	}
	printf("Please input %d vex name:
",vexNum);
	//输入点的信息
	for (int i = 0; i < vexNum; i++)
	{
		printf("i=%d  ", i);
		cin >> G.vexs[i];
	}
	//输入边的的信息
	for ( i = 0; i < e; i++) {
		cin >> x >> y;
		G.edges[LocateVex(G, x)][LocateVex(G, y)] = 1;
		//G.edges[LocateVex(G, x)][LocateVex(G, y)] = 1;无向图
    }
}
2.邻接表
void CreateAdj(AdjGraph*& G, int n, int e) {
	G = new AdjGraph;
	ArcNode* p;
	int x, y;
	G->e = e;
	G->n = n;
	int i, j;
	for (i = 0; i < G->n; i++) {
		G->adjlist[i].firstarc = NULL;//初始化
	}
		
	for (i = 0; i < G->e; i++) {
		cin >> x >> y;//头插法建立节点
		p = new ArcNode;
		p->adjvex = y;
		p->nextarc = G->adjlist[x].firstarc;
		G->adjlist[x].firstarc = p;
		/*
		p = new ArcNode;//无向图
		p->adjvex = x;
		p->nextarc = G->adjlist[y].firstarc;
		G->adjlist[y].firstarc = p;
		*/
	}
}

图遍历

void DFS(MGraph g, int v) {
	int i, j;
	if (visited[v - 1] == 0) {
	visited[v-1] = 1;
	for (i = 0; i<g.n; i++) {
		if (visited[i] == 0) {
			break;
		}
	}
	cout << v<<" ";
		for (j = 0; j < g.n; j++) 
			if (visited[j] == 0 && g.edges[v-1][j] == 1) {
				DFS(g, j + 1);
			}
	
}
void BFS(MGraph g, int v) {
	queue<int> q;
	int i = 0, j;
	for (i = 0; i < g.n; i++)
		visited[i] = 0;
	q.push(v);
	visited[v - 1] = 1;
	while (!q.empty()) {
		v = q.front();
			cout << v << " ";
		for (i = 0; i < g.n; i++) {
			if (g.edges[v - 1][i] && !visited[i]) {
				q.push(i + 1);
				visited[i] = 1;
				
			}
		}
		q.pop();
	}
}

prim算法

void prim(mygragh g)
{
	int lowcost[g.n];
	int close[g.n];
	int i, j, k = 0;
	int count = 0;
		for (i = 0; i < g.n; i++) {
			lowcost[i] = g.edges[0][i];//初始化
			close[i] = 0;
		}
		lowcost[0] = 0;
		for (i = 0; i < g.n - 1; i++)//找出n-1个顶点
		{
			int min = max;
			for (j = 0; j < g.n; j++) {
				if (lowcost[j] != 0 && lowcost[j] < min) {//在V-U中找最近的顶点
					min = lowcost[j];
					k = j;//记录最近顶点编号
				}
			}
			printf("边(%d,%d)权:%d
",closest[k],k,min)
			lowcost[k] = 0;
			for (j = 0; j < g.n; j++) {//进行调整
				if (lowcost[j] != 0 && g.edges[k][j] < lowcost[j]) {
					lowcost[j] = g.edges[k][j];
					close[k] = k;
				}
			}
		}
}

最短路径

//单源最短路径
void Dijkstra(MGraph g, int v) {
	int dist[MaxSize], path[MaxSize];
	int s[MaxSize];
	int i, j, u,temp;
	for (i = 0; i < g.n; i++) {
	dist[i] = g.edges[v][i];
	s[i] = 0;
	if (g.edges[v][i] < INF) path[i] = v;
	else path[i] = -1;
	}
	s[v] = 1; path[v] = 0;
	for (i = 0; i < g.n; i++)
	{
		temp = INF;
		for (j = 0; j < g.n; j++) {
			if (s[j]==0 && dist[j] < temp) {
				u = j;
				temp = dist[j];
			}
		}
	s[u] = 1;	
	for (j = 0; j < g.n; j++) {
		if (!s[j]) {
			if (g.edges[u][j] < INF && dist[u] + g.edges[u][j] < dist[j]) {
				dist[j] = dist[u] + g.edges[u][j];
				path[j] = u;
			}
		}
	}
	}
}
//多源最短路径
void floyd(mygragh g, int A[][MAX], int path[][MAX]) {
	int i, k, j, s;
	int apath[MAX], d;
	for (i = 0; i < g.n; i++) {
		for (j = 0; i < g.n; j++) {
			A[i][j] = g.edges[i][j];
			if (i != j && g.edges[i][j] < INF)
				path[i][j] = i;//i到j有边
			else path[i][j] = -1;//i到j无边
		}
		for (k = 0; k < g.n; k++)
		{
			for(i=0;i<g.n;i++)
				for(j=0;j<g.n;j++)
					if (A[i][j] > A[i][k] + A[k][j])
					{
						A[i][j] = A[i][k] + A[k][j];//修改最短路径长度
						path[i][j] = path[k][j];
					}
		}
	}
}

拓扑排序

void TopSort(AdjGragh* G)
{
	int i, j;
	int st[MAX], top = -1;
	ArcNode* p;
	for (i = 0; i < G->n; i++)//初始化
		G->adjlist[i].count = 0;
	for (i = 0; i < G->n; i++)
	{
		p = G->adjlist[i].firstarc;
		while (!p)
		{
			G->adjlist[p->adjvex].count++;
			p = p->nextarc;
		}
	}
	for (i = 0; i < G->n; i++)//入度为0顶点进栈
		if (G->adjlist[i].count == 0)
		{
			top++;
			st[top] = i;
		}
	while (top > -1)//栈不空
	{
		i = st[top];
		top--;
		cout << i << " ";//出栈
		p = G->adjlist[i].firstarc;
		while (p)//将顶点i出边邻接点入度减1
		{
			j = p->adjvex;
			G->adjlist[j].count--;
			if (G->adjlist[j].count == 0)//入度0的节点入栈
			{
				top++;
				st[top] = j;
			}
			p = p->nextarc;
		}
	}
}

AOV网:

用顶点表示活动,用弧表示活动时间的优先关系的有向图称为顶点表示活动(Activity On Vertex Network)的网,简称AOV网。

AOE网:

用顶点表示事件,用弧表示活动,权表示活动持续时间(Activity On Edge Network)的网,简称AOE网。

①V的最早发生时间:从源点开始到达该顶点的最长路径长度。

②V的最迟发生时间:在不推迟整个工期的前提下,事件V允许的最晚发生时间。

3.疑难问题及解决方案(如果有的话,不求多但求精。可包含编程题,可只包含无解决方案的疑难问题)

这题直接用单源最短路径就可实现,但开始时却一直在图不连通的测试点过不去。后来发现只要输出前再遍历一次,判断每个节点都无相连顶点即可。

原文地址:https://www.cnblogs.com/jmuchenyunfei/p/12904034.html