1.学习总结(2分)
1.1图的思维导图
1.2 图结构学习体会
深度遍历算法
其利用深度优先搜索算法可以产生目标图的相应拓扑排序表,利用拓扑排序表可以方便的解决很多相关的图论问题,如最大路径问题等等。
广度遍历算法
广度优先遍历是连通图的一种遍历策略。因为它的思想是从一个顶点V0开始,辐射状地优先遍历其周围较广的区域,
Prim和Kruscal算法
Prim算法:就是点优先,原始集合里面存放所有的点,目标集合最初为空,先任意从原始集合取一个点放在目标集合,此时开始搜索,原始集合到目标集合最近的一个点,找到后将他放入目标集合,更新原始集合中的点到目标集合的距离,一直将原始集合中的点全部加入到目标集合中,完成搜索。
Kruskal算法:就是边优先,先将每一条边从大到小排序,每次去最小的一条边连接两个点,但是需要判断,是否形成回路。
Dijkstra算法
Dijkstra算法一般的表述通常有两种方式,一种用永久和临时标号方式,一种是用OPEN, CLOSE表的方式,这里均采用永久和临时标号的方式。注意该算法要求图中不存在负权边。
拓扑排序算法
对一个有向无环图G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前
2.PTA实验作业(4分)
2.1 题目1:7-1 图着色问题
2.2 设计思路(伪代码或流程图)
2.3 代码截图
2.4 PTA提交列表说明。
一开始因为自己的疏忽 没有事先在Dev上很好的运行,导致基础的编译错误,理解问题以后仔细检查之后发现是非常不应该的错误,改正以后得以解决。
2.1 7-2 排座位
2.2 设计思路(伪代码或流程图)
2.3 代码截图
2.4 PTA提交列表说明。
一开始因为自己的疏忽 没有事先在Dev上很好的运行,没有全面考虑问题,理解问题以后仔细检查之后发现是非常不应该的错误,改正以后得以解决。
2.1 题目1:7-4 公路村村通
2.2 设计思路(伪代码或流程图)
2.3 代码截图
2.4 PTA提交列表说明。
一开始因为自己的疏忽 没有事先在Dev上很好的运行,导致基础的编译错误,理解问题以后仔细检查之后发现是非常不应该的错误,改正以后得以解决。
3.截图本周题目集的PTA最后排名(3分)
3.1 PTA排名(截图带自己名字的排名)
3.2 我的总分:
200
4. 阅读代码(必做,1分)
#include
#include
#include
#include
#define MAXVEX 6 // 最大顶点数
#define INF 65535
typedef int Status; //Status是函数的类型,其值是函数结果状态代码,如OK等
typedef char VertexType; //顶点类型
typedef int EdgeType; // 边上的权值类型
typedef struct
{
VertexType vexs[MAXVEX]; //顶点表
EdgeType arc[MAXVEX][MAXVEX];//邻接矩阵,可看作边表
int numNodes, numEdges; // 图中当前的顶点数和边数
}MGraph;
// 建立无向网图的邻接矩阵表示
void CreateMGraph(MGraph *G)
{
int i,j,k,w;
printf("输入顶点数和边数:\n");
scanf("%d,%d",&G->numNodes,&G->numEdges); // 输入顶点数和边数
for(i = 0;i
scanf("%c",&G->vexs[i]);
for(i = 0;i
for(j = 0;j
G->arc[i][j]=INF; // 邻接矩阵初始化
for(k = 0;k
{
printf("输入边(vi,vj)上的下标i,下标j和权w:\n");
scanf("%d,%d,%d",&i,&j,&w); // 输入边(vi,vj)上的权w
G->arc[i][j]=w;
G->arc[j][i]= G->arc[i][j]; //因为是无向图,矩阵对称
}
}
int main(void)
{
MGraph G;
CreateMGraph(&G);
return 0;
}
#include
#include
#define MAXVEX 100 //最大顶点数
typedef char VertexType; //顶点类型应由用户定义
typedef int EdgeType; //边上的权值类型应由用户定义
typedef struct EdgeNode//边表结点
{
int adjvex;//邻接点域,存储该顶点对应的下标
EdgeType weight;//用于存储权值,对于非网图可以不需要
struct EdgeNode *next; //链域,指向下一个邻接点
} EdgeNode;
typedef struct VextexNode//顶点表结点
{
VertexType data;//顶点域,存储顶点信息
EdgeNode *firstedge;//边表头指针
} VextexNode, AdjList[MAXVEX];
typedef struct
{
AdjList adjList;
int numNodes, numEdges; // 图中当前顶点数和边数
} GraphAdjList;
voidCreateALGraph(GraphAdjList *Gp)
{
int i, j, k;
EdgeNode *pe;
printf("输入顶点数和边数(空格分隔):");
scanf("%d%d",&Gp->numNodes,&Gp->numEdges);
for (i = 0 ; i < Gp->numNodes; i++)
{
printf("输入顶点信息:");
scanf("%c",&Gp->adjList[i].data);
Gp->adjList[i].firstedge = NULL;//将边表置为空表
}
for (k = 0; k < Gp->numEdges; k++)//建立边表
{
printf("输入边(vi,vj)的顶点序号i,j(空格分隔:");
scanf("%d%d",&i,&j);
pe = (EdgeNode*)malloc(sizeof(EdgeNode));
pe->adjvex = j;//邻接序号为j
//将pe的指针指向当前顶点上指向的结点
pe->next =Gp->adjList[i].firstedge;
Gp->adjList[i].firstedge = pe;//将当前顶点的指针指向pe
pe = (EdgeNode*)malloc(sizeof(EdgeNode));
pe->adjvex = i;
pe->next =Gp->adjList[j].firstedge;
Gp->adjList[j].firstedge = pe;
}
}
int main(void)
{
GraphAdjList GL;
CreateALGraph(&GL);
return 0;
}
pim算法和Kruskal两种实现方法
#include
int arr[101][101];
int main()
{
int n,ttt = 0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&arr[i][j]);
}
}
for(int j=2;j<=n;j++)
{
int min = 100000000;
int index = 0;
for(int i=1;i<=n;i++)
{
if(arr[1][i]==0) continue;
if(arr[1][i] { min = arr[1][i]; index = i; } } ttt += arr[1][index]; for(int i=1;i<=n;i++) { arr[1][i] =arr[1][i] } } printf("%d\n",ttt); return 0; } #include #include #define MAX_VEX_NUM 50 #define MAX_ARC_NUM 100 #define UN_REACH 1000 typedef char VertexType; typedef enum { DG, UDG }GraphType; typedef struct { VertexType vexs[MAX_VEX_NUM]; int arcs[MAX_VEX_NUM][MAX_VEX_NUM]; int vexnum, arcnum; GraphType type; }MGraph; /** * 根据名称得到指定顶点在顶点集合中的下标 * vex 顶点 * return 如果找到,则返回下标,否则,返回0 */ int getIndexOfVexs(char vex,MGraph *MG) { int i; for (i = 1; i <= MG->vexnum; i++) { if (MG->vexs[i] == vex) { return i; } } return 0; } /** * 创建邻接矩阵 */ void create_MG(MGraph *MG) { int i, j, k,weight; int v1, v2, type; char c1, c2; printf("请输入图类型DG(0)和图(1) :"); scanf("%d", &type); if (type == 0) MG->type = DG; else if (type == 1) MG->type = UDG; else { printf("请输入正确的图形类型DG(0)和图(1)"); return; } printf("请输入vexmun : "); scanf("%d", &MG->vexnum); printf("请输入 arcnum :" ); scanf("%d", &MG->arcnum); getchar(); for (i = 1; i <= MG->vexnum; i++) { printf("请输入 %dth vex(char):", i); scanf("%c",&MG->vexs[i]); getchar(); } //初始化邻接矩阵 for (i = 1; i <= MG->vexnum; i++) { for (j = 1; j <= MG->vexnum; j++) { if(i == j) MG->arcs[i][j] = 0; else MG->arcs[i][j] = UN_REACH; } } //输入边的信息,建立邻接矩阵 for (k = 1; k <= MG->arcnum; k++) { printf("请输入 %dth arc v1(char) v2(char) weight(int):", k); scanf("%c %c %d", &c1,&c2,&weight); v1 = getIndexOfVexs(c1, MG); v2 = getIndexOfVexs(c2, MG); if (MG->type == 1) MG->arcs[v1][v2] =MG->arcs[v2][v1] = weight; else MG->arcs[v1][v2] = weight; getchar(); } } /** * 打印邻接矩阵和顶点信息 */ void print_MG(MGraph MG) { int i, j; if(MG.type == DG) { printf("Graph type: Directgraph"); } else { printf("Graph type: Undirectgraph"); } printf("图的顶点数: %d,MG.vexnum"); printf("图弧数: %d,MG.arcnum"); printf("Vertex set:"); for (i = 1; i <= MG.vexnum; i++) printf("%c", MG.vexs[i]); printf("邻接矩阵:"); for (i = 1; i <= MG.vexnum; i++) { j = 1; for (; j < MG.vexnum; j++) { printf("%d", MG.arcs[i][j]); } printf("%d", MG.arcs[i][j]); } } // 定义边结构体 typedef struct { int start; int end; int cost; }Edge; /* * * 由邻接矩阵得到边的信息 * * */ void init_edge(MGraph MG,Edgeedge[]) { int i,j; int count = 0; if(MG.type == 0) { for(i = 1; i <= MG.vexnum;i++) { for (j = 1;j <= MG.vexnum;j++) { if(MG.arcs[i][j] != 0&& MG.arcs[i][j] != UN_REACH) { edge[count].start = i; edge[count].end = j; edge[count].cost =MG.arcs[i][j]; count++; } } } } else { for(i = 1; i <= MG.vexnum;i++) { for (j = i;j <= MG.vexnum;j++) { if(MG.arcs[i][j] != 0 &&MG.arcs[i][j] != UN_REACH) { edge[count].start = i; edge[count].end = j; edge[count].cost =MG.arcs[i][j]; count++; } } } } } /* * * 将边按权值从大到小排序 * */ void sort_edge(Edge edge[],intarcnum) { int i,j; Edge temp; for(i = 0; i < arcnum - 1;i++) { for (j = i+1;j < arcnum;j++) { if(edge[i].cost > edge[j].cost) { temp = edge[i]; edge[i] = edge[j]; edge[j] = temp; } } } } /* * * 输出边的信息 * */ void print_edge(Edgeedge[],int arcnum) { int i = 0; while(i < arcnum) { printf("%d,%d,%d",edge[i].start,edge[i].end,edge[i].cost); i++; } } /** * 找出指定节点的所属的连通分量,这里是找出其根节点在father数组中下标。 **/ int findFather(intfather[],int v) { int t = v; while(father[t] != -1) t = father[t]; return t; } /* * *Kruskal算法求最小生成树 * */ void Kruskal_MG(MGraph MG,Edgeedge[]) { int father[MAX_VEX_NUM]; int i,count,vf1,vf2; // 初始化father数组 for(i = 0;i < MAX_VEX_NUM;i++) { father[i] = -1; } i = 0; count = 0; // 统计加入最小生树中的边数 // 遍历任意两个结点之间的边 while(i < MG.arcnum && count< MG.arcnum) { vf1 = findFather(father,edge[i].start); vf2 = findFather(father,edge[i].end); // 如果这两个节点不属于同一个连通分量,则加入同一个连通分量 if (vf1 != vf2) { father[vf2] = vf1; count++; printf("%c,%c,%d",MG.vexs[edge[i].start],MG.vexs[edge[i].end],edge[i].cost); } i++; } } /** * 主函数 */ int main(void) { MGraph MG; Edge edge[MAX_ARC_NUM]; create_MG(&MG); print_MG(MG); init_edge(MG,edge); sort_edge(edge,MG.arcnum); printf("the result of Kruskal:"); Kruskal_MG(MG,edge); return EXIT_SUCCESS; }