博客作业06--图

1.学习总结(2分)

1.1图的思维导图

1.2 图结构学习体会

图的遍历

  • 图的深度优先遍历是从初始点v出发,以纵向的方式逐渐访问各个顶点,一旦找不到相邻的顶点就回退,需要递归的过程,广度遍历是类似层次遍历,利用队列来一一访问

Prim和Kruscal算法

  • Prim和Kruscal算法,Prim算法是多次寻找邻边的权重最小值,而Kruskal是需要先对权重排序后查找的,Kruskal在算法效率上是比Prim快的,因为Kruskal只需一次对权重的排序就能找到最小生成树,而Prim算法需要多次对邻边排序才能找到

Dijkstra算法

  • Dijkstra算法,在无向图 G=(V,E) 中,假设每条边 E 的长度为 w,找到由顶点 V0 到其余各点的最短路径
  • 主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止

拓扑排序

  • 拓扑排序:是将一个有向无环图G的所有的顶点排成一个线性序列,使得有向图中的任意的顶点u 和 v 构成的弧,(u, v) 属于该图的边集,并且使得 u 始终是出现在 v 前面
  • 只有有向无环图才可以进行拓扑排序
  • 算法思想:1.找到有向无环图中没有前驱的节点(或者说是入度为0的节点)输入;2.然后从图中将此节点删除并且删除以该节点为尾的弧

2.PTA实验作业(4分)

2.1 题目1:7-1 图着色问题

2.2 设计思路(伪代码或流程图)

     输入顶点数与边数,颜色数进行建图
     深度遍历并将其结果储存于数组d中
     输入待检查的颜色分配方案的个数num
    for( ;num;num--){
            for j=1 to 顶点数{
             输入颜色的分配方案,统计所用颜色总数sum
              }
         若统计的颜色总数sum!=题干的颜色数     
              则把flag由0赋为1
      }
         将颜色按深度遍历排序储存在数组c中
          for i=0 to 顶点数{
                for j=0 to 顶点数{
                  若有相邻的颜色相同
                      则把flag的值由0赋为1
               }
             flag值已为1即已有相邻颜色相同停止循环
      }
   如果flag=1 输出no 否则 输出yes

2.3 代码截图(注意,截图、截图、截图。代码不要粘贴博客上。不用用···语法去渲染)

2.4 PTA提交列表说明。

答案错误

部分正确




一开始数值赋不进去,只能输出两个,后发现自己在sum这里判断颜色数目时错误直接返回,出错了

改正后输出正常但是输出不对,比样例输出有一个no

自己的循环变量不对,在num循环那里自己忘记循环内有用i,重复使用变量i;

自己的循环条件出错。。。

2.1 题目2:7-3 六度空间

2.2 设计思路(伪代码或流程图)

int bfs(int v)  
{  
    初始化队列
    while(队不空)  
    {  
       出队元素v
        for  i=1 to 顶点数
        {  
            若G[v][i]==1 && vis[i]==0
            {  
                count++;  
               把i进队
                tail=i;  
            }  
        }  
       若v为该层最后一个结点
        {  
            层数++
            更新层末的顶点
        }  
       若层数为6
            跳出循环
    }  
    返回count的值
} 

2.3 代码截图(注意,截图、截图、截图。代码不要粘贴博客上。不用用···语法去渲染)

2.4 PTA提交列表说明。



段错误

自己最早用构建邻接矩阵的方式进行赋值,但是赋不进去,总是强制退出,后改为定义二维数组赋值才能很好运行,才正确

2.1 题目3:7-4 公路村村通

2.2 设计思路(伪代码或流程图)

int Prim(int G[MAXV][MAXV],int v)//prim算法计算最短路径 
{
   定义数组 lowcost[MAXV],closest[MAXV];
   lowcost[1]=0;
   closest[1]=0;
   for i=2 to 顶点数 {
   	lowcost[i]=G[v][i];
   	closest[i]=v;
  } 
   for i=2 to 顶点数 {
   	min置为INFINITY
   	for j=2 to 顶点数 {
   		在(V-U)中找出离U最近的顶点k
                k记录最近顶点的编号
    }
	  以last更新记录权值长度
	  lowcost[k]=0;
	  for j=2 to 顶点数{
	  	若 顶点未被访图联通{
	  		更新
                   k记录最近顶点
		  }
	  }
   }
   返回last的值
}

2.3 代码截图(注意,截图、截图、截图。代码不要粘贴博客上。不用用···语法去渲染)

2.4 PTA提交列表说明。



部分正确

自己一开始只有-1的那个点正确


后发现自己的prim算法有问题,是自己的last忘记赋初值


后面的部分正确是自己循环问题,在循环时少了等于,最后一层循环

编译错误

自己的选择c与c++的选择错误

3.截图本周题目集的PTA最后排名(3分)

本次题目集总分:310分

3.1 PTA排名

3.2 我的总分:222

本题评分规则:

(1)PTA总分310分:3分(全部题目都做)
(2)PTA总分在250分--310分:2.5分(大部分做完1)
(3)PTA总分在200--250分:2分(大部分做完2)
(4)PTA总分在150--200分:1.5分
(5)PTA总分在60分-150分:1分
(6)PTA总分在60分以下:0分

4. 阅读代码(必做,1分)

#include<iostream>  
using namespace std;  
#include<cstring>  
#include<cstdio>  
#include<queue>  
#define inf 0x3f3f3f3f  
struct spe  
{  
    int next,to,from;  
    int len,time;  
};  
spe edge[250001];  
int head[501];  
int cnt = 1;  
int n,m;  
bool cmp( vector<int> a,vector<int> b )  
{  
    if( a.size() != b.size() )  
        return false;  
    for( int i= 0 ; i < a.size() ; i++ )  
        if( a[i] !=b[i] )  
            return false;  
    return true;  
}  
void add(int a,int b,int len,int time)  
{  
    edge[cnt].from = a;  
    edge[cnt].to = b;  
    edge[cnt].len = len;  
    edge[cnt].time = time;  
    edge[cnt].next = head[a];  
    head[a] = cnt;  
    cnt++;  
}  
struct node_num  
{  
    int prev,num;  
};  
node_num node[501];  
struct node_time  
{  
    int prev,len;  
};  
node_time nod[501];  
int spfa_time( int start, int end )  
{  
    queue<int> q;  
    int visit[501];  
    int dis[501];  
    memset(visit,0,sizeof(visit));  
    memset(dis,0,sizeof(dis));  
    memset(nod,0,sizeof(nod));  
    for( int i = 0 ; i < n ; i++ )  
        nod[i].len = inf;  
    nod[0].prev = inf;  
    nod[start].prev = start;  
    nod[start].len = 0;  
    for( int i = 0 ; i < n ; i++ )  
        dis[i] = inf;  
    q.push(start);  
    dis[start] = 0;  
    visit[start] = 1;  
    while( !q.empty() )  
    {  
        int t = q.front();  q.pop();  
        for( int i = head[t] ; i != -1 ; i = edge[i].next )  
        {  
            if( dis[t] + edge[i].time < dis[ edge[i].to ] )  
            {  
                dis[ edge[i].to ] = dis[t] + edge[i].time;  
                nod[ edge[i].to ].prev = t;  
                nod[ edge[i].to ].len = nod[t].len+edge[i].len;  
                if( visit[edge[i].to] == 0 )  
                {  
                    visit[edge[i].to] = 1;  
                    q.push(edge[i].to);  
                }  
            }  
            else if( dis[t] + edge[i].time == dis[ edge[i].to ] )  
            {  
                if( nod[t].len + edge[i].len < nod[ edge[i].to ].len )  
                {  
                    nod[ edge[i].to ].len = nod[t].len + nod[ edge[i].to ].len;  
                    nod[ edge[i].to ].prev = t;  
                }  
            }  
        }  
    }  
    return dis[end];  
}  
int spfa_len( int start, int end )  
{  
    queue<int> q;  
    int visit[501];  
    int dis[501];  
    memset(visit,0,sizeof(visit));  
    memset(dis,0,sizeof(dis));  
    memset(node,0,sizeof(node));  
    for( int i = 0 ; i < n ; i++ )  
        node[i].num = inf;  
    node[0].prev = inf;  
    node[start].prev = start;  
    node[start].num = 0;  
    for( int i = 0 ; i < n ; i++ )  
        dis[i] = inf;  
    q.push(start);  
    dis[start] = 0;  
    visit[start] = 1;  
    while( !q.empty() )  
    {  
        int t = q.front();  q.pop();  
        for( int i = head[t] ; i != -1 ; i = edge[i].next )  
        {  
            if( dis[t] + edge[i].len < dis[ edge[i].to ] )  
            {  
                dis[ edge[i].to ] = dis[t] + edge[i].len;  
                node[ edge[i].to ].prev = t;  
                node[ edge[i].to ].num = node[t].num+1;  
                if( visit[edge[i].to] == 0 )  
                {  
                    visit[edge[i].to] = 1;  
                    q.push(edge[i].to);  
                }  
            }  
            else if( dis[t] + edge[i].len == dis[ edge[i].to ] )  
            {  
                if( node[t].num + 1 < node[ edge[i].to ].num )  
                {  
                    node[ edge[i].to ].num = node[t].num + 1;  
                    node[ edge[i].to ].prev = t;  
                }  
            }  
        }  
    }  
    return dis[end];  
//  cout<<"LEN:"<<dis[end]<<endl;  
}  
int main()  
{  
    while( scanf("%d %d",&n,&m) == 2 )  
    {  
        memset(head,-1,sizeof(head));  
        for( int i = 1 ; i <= m ; i++ )  
        {  
            int a,b,c,d,e;  
            scanf("%d %d %d %d %d",&a,&b,&c,&d,&e);  
            add(a,b,d,e);  
            if( c == 0 )  
                add(b,a,d,e);  
        }  
        int start,end;  
        scanf("%d %d",&start,&end);  
        int LEN = spfa_len(start,end);  
        int TIME = spfa_time(start,end);                    //两个spfa  
        vector<int> len,time;  
        int t = end;  
        while( node[t].prev != t )  
        {  
            len.push_back(t);  
            t = node[t].prev;  
        }  
        len.push_back(start);           //prev数组顺序是反的  
        t = end;  
        while( nod[t].prev != t )  
        {  
            time.push_back(t);  
            t = nod[t].prev;  
        }  
        time.push_back(start);  
        if( cmp(len,time) )  
        {  
            printf("Time = %d; Distance = %d:",TIME,LEN);  
            for( int i = time.size() - 1 ; i >= 0 ; i-- )  
            {  
                if( i )  
                    printf(" %d =>",time[i]);  
                else printf(" %d\n",time[i]);  
            }  
        }  
        else  
        {  
            printf("Time = %d:",TIME);  
            for( int i = time.size() - 1 ; i >= 0 ; i-- )  
            {  
                if( i )  
                    printf(" %d =>",time[i]);  
                else printf(" %d\n",time[i]);  
            }  
            printf("Distance = %d:",LEN);  
            for( int i = len.size() - 1 ; i >= 0 ; i-- )  
            {  
                if( i )  
                    printf(" %d =>",len[i]);  
                else printf(" %d\n",len[i]);  
            }  
        }  
    }  
    return 0;  
} 

这是天梯地图的代码

代码链接:https://blog.csdn.net/qq_39627843/article/details/79121977

该代码用spfa算法:https://blog.csdn.net/xunalove/article/details/70045815

该代码加入一个pre数组,某一点的时间和之前的时间相同,我们就判断他们的距离是否可以更新,在更新dis数组的同时更新pre数组

spfa的算法思想(动态逼近法):设立一个先进先出的队列q用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点###v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止。

posted @ 2018-06-17 21:37  hahaha233  阅读(237)  评论(0编辑  收藏  举报