图-总结

1.思维导图

2.重要概念

1.DFS算法

简单的说就是从一个顶点开始,不断的深入访问,当无法访问时再返回到上一级,直到完全访问完。
代码如下:

void DFSTravse(MyGraph& G,int v)//深度优先,采用递归思想,利用邻接表
{
	int w;
	cout << G.vexs[v]<<" ";
	visited[v] = 1;
	for (w = 0; w < G.vexNum; w++)
	{
		if (G.arcs[v][w] != 0 && visited[w] == 0)
			DFSTravse(G, w);
	}
}

2.BFS算法

简单说,有点类似树的层序遍历,要利用到队列,从一个顶点开始,把它和它邻接的点入队,输出一个邻接点时再把这个邻接点的邻接点入队,直到队空。
代码如下:

void BFS(MyGraph* G, int v) {
	for (int i = 1; i <= G->n; i++) visited[i] = 0;//利用邻接表
	ArcNode* p;
	int t;
	queue<int>Q;
	printf("%d", v);
	visited[v] = 1;
	Q.push(v);
	while (!Q.empty()) {
		t = Q.front();
		Q.pop();
		p = G->adjlist[t].firstarc;
		while (p != NULL) {
			if (visited[p->adjvex] == 0) {
				printf(" %d", p->adjvex);
				visited[p->adjvex] = 1;
				Q.push(p->adjvex);
			}
			p = p->nextarc;
		}
	}
}

3.最小生成树

1.prim算法
简而言之,核心是利用贪心算法,先从一个顶点开始,选择权值最小的邻接点,把这两个点加入到一个集合中,
再从这两个点中找权值最小的邻接点,再把该邻接点加入到集合中,重复以上操作,直到点全找完。

代码如下:

void MiniSpanTree_Prim(MGragh G)
{
    int mini,i,j,k;
    int adjvex[MAXVEX];
    int lowcost[MAXVEX]; 
    lowcost[0] = 0;
    //ps:lowcost[i] = 0 
    adjvex[0] = 0; 
    for(i = 0; i < G.numVertexes; i++)
    {
        lowcost[i] = G.arc[0][i];
        adjvex[i] = 0;
    }
    for(i = 1; i < G.numVertexes; i++) 
    {
        mini = INFITINY; 
        j = 1;
        k = 0;
        while(j < G.numVertexes)
        {
            if(lowcost[j] != 0 && lowcost[j] < mini)
            {
                mini = lowcost[j];
                k = j;
            }
            j++;
        }
        printf("(%d %d)",lowcost[k],k);
        lowcost[k] = 0;
        for(j = 1; j < G.numVertexes; j++)
        {
            if(lowcost[j] != 0 && G.arc[k][j] < lowcost[j])
            {
                lowcost[j] = G.arc[k][j];
                adjvex[j] = k;
            }
        }
    }
}

2.Kruskal算法
这个算法也是利用贪心算法,描述起来要更简单一些,它是先在所有的边中找权值最小的边,
再从剩下的边中找最小的边,即贪心算法,但是不能出现回路,直到所以点都有边相连。

4.最短路径

这个算法利用了两个数组,即Dist[]和Path[].Dist[]用来记录路径长度,Path[]用来记录每个节点的前驱。
具体方法是从顶点V开始,把到每个节点的路径长度计入Dist[],把每个节点的前驱计入Path[].再从Dist[]里
找路径最小的点,和顶点加入一个集合,接下来从新计算到各点的路径,比原来小的话,就更新两个数组,直到
所以的店都加入集合。
例子:

从而得出最短路径:

5.拓扑排序

找到一个入度为零的点,从这个点开始把它和它的边去掉,再找下一个入度为零的点,重复上述操作,直到所有的点都找完,
就能得到一个拓扑序列,如果最后还有剩余的点就说明该图不是有向无环图。
例如:

这题可以从5开始也可从1开始,然后继续找入度为零的点就行,答案不唯一的。

6.疑难问题及解决方案

图的着色问题

#include<iostream>

using namespace std;

#define MAXVEXNUM 501
//点,边
typedef  int ArcCell;
typedef char VexType;

typedef struct {
    VexType vexs[MAXVEXNUM];//点的集合
    ArcCell arcs[MAXVEXNUM][MAXVEXNUM];//边的集合
    int vexNum, arcNum;
    int color[MAXVEXNUM];
}MyGraph;

void CreateDGraphFromConsole(MyGraph& G, int vexNum, int arcNum);
int JudgeGraph(MyGraph& G);

int main() {
    int n, i, e, k, j, m,t,x;
    int min,max;
    int V[MAXVEXNUM];
    MyGraph G;
    cin >> n >> e>>k;
    CreateDGraphFromConsole(G, n, e);
    cin >> m;
    for (i = 0; i < m; i++) {
        min = 500;
        max = 0;
        t = 0;
        for (j = 0; j < n; j++) {
            cin >> G.color[j];
            for (x = 0; x < t; x++) {
                if (V[x] == G.color[j])
                    break;
            }
            if (x == t) {
                V[t++] = G.color[j];
            }
        }
        if (t != k) {
            cout << "No" << endl;
        }
        else {
            if (JudgeGraph(G))
                cout << "Yes" << endl;
            else
                cout << "No" << endl;
        }
    }
}
void CreateDGraphFromConsole(MyGraph& G, int vexNum, int arcNum) {
    int i, j, k;
    int a,b;
    G.vexNum = vexNum;
    G.arcNum = arcNum;
    for (i = 0; i < vexNum; i++) {
        for (j = 0; j < vexNum; j++)
            G.arcs[i][j] = 0;
    }
    for (k = 0; k < arcNum; k++) {
        cin >> a >> b;
        G.arcs[a-1][b-1] = 1;
        G.arcs[b-1][a-1] = 1;
    }
}
int JudgeGraph(MyGraph& G) {
    int i, j;
    for (i = 0; i < G.vexNum; i++) {
        for (j = 0; j < G.vexNum; j++) {
            if (G.arcs[i][j]) {
                if (G.color[i] == G.color[j])
                    return 0;
            }
        }
    }
    return 1;
}

刚开始还不懂,后来老师讲解了,其实就是把邻接矩阵的每一行都遍历过去,看颜色是否重复。

posted @ 2020-05-17 16:35  123yj  阅读(211)  评论(0编辑  收藏  举报