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.疑难问题及解决方案(如果有的话,不求多但求精。可包含编程题,可只包含无解决方案的疑难问题)
这题直接用单源最短路径就可实现,但开始时却一直在图不连通的测试点过不去。后来发现只要输出前再遍历一次,判断每个节点都无相连顶点即可。