1.1图的思维导图
图的存储结构--图的遍历---最小生成树--最短路径---拓扑排序、关键路径
1.2 图结构学习体会
谈谈你对图结构中的几个经典算法学习体会。具体有:
深度遍历算法:
1 其规则:从图的某个初始顶点v出发,首先访问初始顶点v,然后选择一个与定点v相邻且没有被访问过的顶点w为下一个初始顶点,再从w出发进行深度优先遍历,知道图中与当前顶点v邻接的所有顶点都被访问过为止。
2 采用递归的方法一般采用邻接表为其算法的存储结构,因为要判断顶点是否访问所以需要设立一个全局数组visited[]来标记。
3时间复杂度为O(n+e)用邻接矩阵时时间复杂度为O(n*n)
4注意 对于非连通的DFS算法需要改进 通过加一个for()循环使其遍历所有节点,因为单独的深度遍历只能检索一个连通图
广度遍历算法:
1 其规则:首先访问初始顶点v,接着访问顶点v的所有未被访问过的邻接点,依次类推,直到图中所有和初始顶点v有路径相通的顶点都被访问过为止。
2 采用循环嵌套方式以邻接表为存储结构,通过一个队列的出入队来标记是否访问过。
3 时间复杂度同深度遍历
4 注意 其算法类似于树的层次遍历,对于非连通图也需要注意用for来实现多次检索
Prim和Kruscal算法:
算法P主要是以顶点为基础,通过顶点与顶点之间的最小边来修改边集,当新加入顶点出现新的最小边,局部最优时,修改。的算法K以边为基础,按权值大小从最小的边选择起。
Dijkstra算法 :1 从一个顶点到其余各顶点的最短路径,其精髓就是不断地对 dist path 数组的值进行修正,在每一次加入新的节点后找出最短路径
2 对此算法,证明了一点:如果一条路径是最短路径,那么这条路上所有的子路径都为最短路径。
3 与之对应的弗洛伊德算法可以求出每对顶点之间的最短路径。
拓扑排序算法
1 与深度遍历结合可以检测是否产生环路
2 在一个有向图中找到一个拓扑序列的过程(有向无环图)
2.1 题目1:7-1 图着色问题(25 分)
图着色问题是一个著名的NP完全问题。给定无向图G=(V,E),问可否用K种颜色为V中的每一个顶点分配一种颜色,使得不会有两个相邻顶点具有同一种颜色?
但本题并不是要你解决这个着色问题,而是对给定的一种颜色分配,请你判断这是否是图着色问题的一个解。
2.2 设计思路(伪代码或流程图)
int main(){
定义变量
输入所需要处理的颜色分配scanf("%d%d%d",&v,&e,&k);
for(int i = 0;i<e;i++){
输入
对应入栈
}
scanf("%d",&num);
while(num--){
bool flag = true;
清零初始化
for(int i = 1;i <= v;i++){
scanf("%d",&color[i]);
读入着色
}
if(不符合图着色对应要求)
flag = false;
for(int i = 1;i <= v;i++){
for(int j = 0;j < mp[i].size();j++){
双重循环判断邻接矩阵存储模式下的图颜色
}
}
if(!flag)
break;
}
根据flag值 输出是否符合条件
}
return 0;
}
2.3 代码截图(注意,截图、截图、截图。代码不要粘贴博客上。不用用···语法去渲染)
2.4 PTA提交列表说明。
通过和同学讨论代码和借鉴网上的代码。
一个通过判断着色数目,如果分配数目和给题目的颜色数目的不相等则返回false
如果相邻的顶点颜色相同也返回false。 从两方面判断
2.1 题目2:7-2 排座位(25 分)
布置宴席最微妙的事情,就是给前来参宴的各位宾客安排座位。无论如何,总不能把两个死对头排到同一张宴会桌旁!这个艰巨任务现在就交给你,对任何一对客人,请编写程序告诉主人他们是否能被安排同席。
2.2 设计思路(伪代码或流程图)
int Find(int arr[],int x)
{
while(x != arr[x])
x = arr[x];
return x ;
}
void join(int a,int b)
{
定义调用find函数
if(x != y)
{
判断是否相等
}
}
int main()
{
定义变量
输入
for(int i = 0 ; i < MAX ; i ++)
{
循环赋值
}
for(int i = 0 ; i < M ; i ++)
{
输入
if(cc == 1)
{
满足条件调用 join
}
else
{
对应赋1
}
}
for(int i = 0 ; i <K ; i ++)
{
scanf("%d%d" , &t1 , &t2);
定义赋值
根据条件判断是那种类型的座位排列,输出相应的话语
}
return 0 ;}
2.3 代码截图(注意,截图、截图、截图。代码不要粘贴博客上。不用用···语法去渲染)
2.4 PTA提交列表说明。
一开始的编译错误是以为没有切换c环境,后面发现不是这个问题是因为头文件没有写好,因为参考网上代码所以开始觉得不需要用到某些文件就删掉了。后来把一些有用到库函数或者其他条件的全部改成c语言再运行发现还是编译错误,就重新根据原来的再敲过了。
从
2.1 题目3:7-8 城市间紧急救援(25 分)
作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图。在地图上显示有多个分散的城市和一些连接城市的快速道路。每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上。当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队。
2.2 设计思路(伪代码或流程图)
库函数调用
定义变量
定义结构体
int cmp(const voida,const voidb) {
根据判断返回对应值
}
int main() {
定义结点数、边数、起点、终点
初始化地图上的结点
for(int i=0; i<N; Map[i++].right=0);
for(int i=0; i<N; scanf("%d",&teams[i++]));
读入救援队数量
{
读入地图信息,并排序整理
}
for(int i=0; i<N; i++) {
qsort(Map[i].Reached,Map[i].right,sizeof(data),cmp);分配
for(int j=0; j<Map[i].right; j++) {
}
}
}
for(int i=0; i<N; Lenth[i++][0]=FULL);
初始化
Dijkstra(S);调用算法
printf("%d %d\n",Lenth[D][2],Lenth[D][1]);
DFS(D,S);深度遍历,
printf("%d",D);
return 0;
}
2.3 代码截图(注意,截图、截图、截图。代码不要粘贴博客上。不用用···语法去渲染)
2.4 PTA提交列表说明。
最开始的部分错误是因为最后一个if判断条件写错,把规定的0 1 2记错所测试点只对了一个。
后来的编译错误是修改的时候忘记切换输入法导致出现中文字符。
3.截图本周题目集的PTA最后排名(3分)
本次题目集总分:310分
3.1 PTA排名(截图带自己名字的排名)
- 阅读代码(必做,1分)
读的
这个人的有关于六度空间的代码
sum++;/当每出一个点,代表这个点是扩散成功的,即可到达的点数加一 ,通过sum累加实现
for(i = head[u.cen] ; i != -1 ; i = e[i].next) //所有和这个点相邻的点,都需要被扩散 去找其他的关系
{
if(vis[e[i].y]) //注意这里的标记是必须要有判断的,否则当1-2到达了中心点为2的node的时候,由于存储了2-1,中心点就又会回到1,循环往复导致无法跳出循环
continue;
vis[e[i].y] = 1;
v.cen = e[i].y;
v.step = u.step + 1;
q.push(v);
}
}
return sum;
}
int main() //主函数
{
int i, a, b, j;
scanf("%d %d", &n, &m);
memset(head, -1, sizeof(head));
for(i = 0 ; i < m ; i++)
{
scanf("%d %d", &a, &b);
e[i].x = a;//注意无向图邻接矩阵的建立
e[i].y = b;
e[i].next = head[a];
head[a] = i;
e[i + m].x = b;
e[i + m].y = a;
e[i + m].next = head[b];
head[b] = i + m;
}
float t;
for(i = 1 ; i <= n ; i++)
{
memset(vis, 0, sizeof(vis)); //这个函数是库函数中用于初始化的函数
t = bfs(i) * 100.0 / n;
printf("%d: %.2lf%%\n", i, t);
}
return 0;
}