zoukankan      html  css  js  c++  java
  • DS博客作业06--图

    1.本周学习总结(0--2分)

    1.1思维导图

    1.2谈谈你对图结构的认识及学习体会。

    图结构,它不再像线性表和树结构那样数据之间存在一对一或一对多的关系,它是数据的多对多的一种表现,在用代码表示上,它可以用邻接表和邻接矩阵来写:邻接矩阵,感觉就是二维数组,书本运用了用了两个结构体,一个是顶点的类型,而另一个是完整的图邻接矩阵类型;而邻接表就是不同于邻接矩阵关于图的另外一种表示,书本上运用了三种结构体,也在结构体中运用了一个结构体指针,相较于邻接表来说较难理解,这三个结构体一个用来存放头节点,一个用来存放后续结点,而剩下的就是存放完整的图邻接表。这两种表示存储结构各有各的特点,关于图的遍历分为深度与广度,深度遍历和广度遍历一个运用在图中唯一一次的遍历,一个运用了队列,比起后面的生成树与最短路径简单一些,而生成树可以由普里姆算法和克鲁斯卡尔算法来实现,普里姆算法与贪心算法相类似,只不过还用了一个数组来存放候选边,而克鲁斯卡尔算法则是将最短路径先选出来,然后再连起来。对于这两种算法,看一下还是勉强能懂的,但要写肯定写不出来。
    

    2.PTA实验作业(6分)

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

    2.1.1设计思路

    宏定义数组visited并将初值置为0,定义数组d来储存路径;
    宏定义二维数组a[501][501]来存储图的边 
    void dfs(int i)
           定义 j;
           d[k++]=i;
           标记结点已遍历; 
           for j=1 to v do       
               if 存在边 且 结点未被访问 then 
    		       dfs(j);
               end if
           end for
    void dfs1()
        定义 i;
        for i=1 to v
            if 结点未被访问 then
                 dfs(i); 
        end for
    
    
    int main()
        输入v、e、z;
        输入存在的边,并在二维将二维矩阵置为1;1 
        调用dfs1函数; 
        输入n;
        while n--
         初始化 b[501]={0},c[501],e[501],sum=0,flag=1;
         for i=1 to v;i++)
            输入c[i];
            b[c[i]]++;
            if b[c[i]]等于1 then sum++;
         end for 
         if sum不等于z then 
    	    flag=0;
         end if
         for i=0 to k do 
    	    e[i]=c[d[i]];
         end for
         for i=0 to k
            forj=0 to k     
            if a[d[i]][d[j]]等于1并且e[i]等于e[j] then
                flag=0;
                break;
            end if
            if flag等于0 then break;
         end for 
         if flag等于0 then 
    	    输出No
    	 end if
         else 
    	    输出Yes
        end 
        return 0
    

    2.1.2代码截图


    2.1.3本题PTA提交列表说明。


    1.老师上课讲过要用深度遍历来写,然后看完课本后来写这道题,多加了一个递归口,导致程序没有完全执行完就停止了;
    2.写完深度遍历的那一部分,没有完全懂这道题的思路,然后上网查了一下,理解了一遍来写,还是有一些小细节没做好。

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

    2.2.1设计思路

    宏定义visit数组存放被访问过的结点 
    宏定义二维数组arr来存放边的信息 
    int BFS(int v)                  //先使用广度遍历,然后记录在范围在六个之间的结点个数 
    	新建整型队列q; 
        定义level存放结点距离, 定义tail存放与需要访问结点相关的结点, 定义last暂时存放需要遍历的结点, 定义count存放相关结点个数;
    	需要访问的结点入队;
    	标记结点已经被访问; 
    	while 队列不空 do 
    		取队尾元素; 
    		出队; 
    		for i=1 to N do 
    			if  两个结点之间存在边 且 第二个顶点没被访问过 then
    				相关结点个数加一; 
    				tail = i;
    				标记结点已经被访问; 
    				出队; 
    			end if 
    		if temp == last then 
    			level++;             //结点距离加一 
    			last = tail;         //last下移到下一个相关结点 
    		end if
    		if level == 6 then break;//如果结点距离超过六,退出循环 
        end 
    	return count;
    int main() 
    	输入N,M; 
    	输入邻接表信息; 
    	for i=0 to N then
    	    使用BFS函数计算;
    	    初始化visit数组; 
    		输出; 
        return 0;
    

    2.2.2代码截图


    2.2.3本题PTA提交列表说明。


    1.老师上课讲到这道题时,讲到要用上广度遍历,自己敲的时候,还是把广度遍历的算法敲错了,导致程序运行不来;
    2.后面思考怎么统计结点个数时,想到用数组来记录个数,但是退出程序时的那个条件出错了,导致输出的结点只到8,9,后面改了循环条件,发现还是没有完全输出,又看了看建图函数,发现里面的循环条件出错了,导致间的图不完全。
    3.输出是不知道c++如何精确到小数点后两位,后来百度了一下,可以用etiosflags(ios::fixed) << setprecision(2) 来写。

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

    2.3.1设计思路

    宏定义Minimum无穷大 
    宏定义二维数组Map存放边的信息 
    宏定义visit数组存放被访问过的结点 
    宏定义lowcos存储每个顶点与之相连边的权值
    int prim()
        int i,j,k;
        int sum =0,flag=0;
        标记结点已经被访问; 
        权值初始化
        for i=2 to n do
            Min  = Minimum;
            for j=1 to n then             //寻找每个顶点与之相连的边的最小权值
                if !visit[j]&&lowcost[j]<Min then
                    Min = lowcost[j];
                    k=j;
            end for
            if Min==Minimum then           //如果某个顶点与之相连的边找不到最小权值,则表示道路不通
                flag = 1;
                break;
            sum+=Min;
            标记结点已经被访问;
            for j=1 to n do                   //纠正权值 
                if !visit[j]&&lowcost[j]>Map[j][k] then 
                    lowcost[j]=Map[j][k];
        if flag==0                             //存在公路 
            输出sum; 
        else
            输出-1; 
    int main()
        while cin>>n>>m do
    	    为map与visit置初值; 
            初始化map
            调用prim函数 
        return 0;
    

    2.3.2代码截图


    2.3.3本题PTA提交列表说明。


    1.不知道无法畅通的情况怎么处理,后来又定义了一个无穷大的变量与最小的路径进行标胶,如果最小的路径等于无穷大,则说明没有路径即无法正常畅通。
    2.这道题是使用prim来写,当时还是在没有完全掌握prim算法上来写,没把候选边的那一部分写上去。

    3、上机考试错题及处理办法

    3.1.

    题目:
    6-1 jmu-ds-最短路径

    错误代码:

    错的原因:
    由于pta上的图的作业集没有这道题,然后就没认真看,当时写这道题的时候完全是按照老师讲课时的印象写的,和根据自己印象中的prim算法写的,结果当然是错的。考完后又看了看书本,按照理解再敲了一遍。
    处理方法:

    3.2

    题目:
    7-2 公路村村通
    错误代码:
    ![](https

    错的原因:
    这道题是根据舍友提供的思路来敲的,后来百度了这一道题,发现自己在处理prim算法时发现时间复杂度过大,导致答案输不出来。
    处理方法:

    3.3

    7.3
    在考试时还没来得及做

    
    #include<bits/stdc++.h>
    using namespace std;
    #define INF 0x3f3f3f3f
    const int maxn = 503;
    int n,m,s,en;
    bool vis[maxn];
    int dis[maxn];
    int pre[maxn];
    int cnt[maxn];
    struct node
    {
        int v,c,di;
        node()
        {
            v = c = di = 0;
        }
        node(int a,int b)
        {
            v = a;
            c = b;
            di = 0;
        }
        node(int a,int b,int cc)
        {
            v = a;
            c = b;
            di = cc;
        }
        bool operator<(const node &a)const
        {
            return c>a.c;
        }
    };
    vector<node>vec1[maxn];//dis
    vector<node>vec2[maxn];//time
    priority_queue<node> que;
    void addEdge1(int u,int v,int w,int x)
    {
        vec1[u].push_back(node(v,w,x));
    }
    void addEdge2(int u,int v,int w,int x)
    {
        vec2[u].push_back(node(v,w,x));
    }
    void dijkstra2()
    {
        for(int i=0; i<n; i++)
            pre[i] = i;
        memset(vis,false,sizeof(vis));
        for(int i=0; i<=n; i++)
        {
            dis[i] = INF;
            cnt[i] = 0;
        }
        while(!que.empty())
            que.pop();
        dis[s] = 0;
        pre[s] = -1;
        cnt[s] = 0;
        que.push(node(s,0));
        node tmp;
        while(!que.empty())
        {
            tmp = que.top();
            que.pop();
            int u = tmp.v;
            if(vis[u])continue;
            vis[u] = true;
            int l = vec2[u].size();
            for(int i=0; i<l; i++)
            {
                int v = vec2[u][i].v;
                int cost = vec2[u][i].c;
                int juli = vec2[u][i].di;
                if(!vis[v] && dis[v] > dis[u]+cost)
                {
                    cnt[v] = cnt[u]+juli;
                    dis[v] = dis[u] + cost;
                    pre[v] = u;
                    que.push(node(v,dis[v]));
                }
                else if(!vis[v] && dis[v] == dis[u]+cost)
                {
                    if(cnt[v] > cnt[u] + juli)
                    {
                        pre[v] = u;
                        cnt[v] = cnt[u]+juli;
                    }
                }
            }
        }
    }
    void dijkstra1()
    {
        for(int i=0; i<n; i++)
            pre[i] = i;
        memset(vis,false,sizeof(vis));
        for(int i=0; i<=n; i++)
            {
                dis[i] = INF;
                cnt[i] = INF;
            }
        while(!que.empty())
            que.pop();
     
     
        dis[s] = 0;
        pre[s] = -1;
        cnt[s] = 1;
        que.push(node(s,0));
        node tmp;
        while(!que.empty())
        {
            tmp = que.top();
            que.pop();
            int u = tmp.v;
            if(vis[u])continue;
            vis[u] = true;
            int l = vec1[u].size();
            for(int i=0; i<l; i++)
            {
                int v = vec1[u][i].v;
                int cost = vec1[u][i].c;
                if(!vis[v] && dis[v] > dis[u]+cost)
                {
                    cnt[v] = cnt[u]+1;
                    dis[v] = dis[u] + cost;
                    pre[v] = u;
                    que.push(node(v,dis[v]));
                }
                else if(!vis[v] && dis[v] == dis[u]+cost)
                {
                    if(cnt[v] > cnt[u] +1)
                    {
                        pre[v] = u;
                        cnt[v] = cnt[u]+1;
                    }
                }
            }
        }
    }
    bool panduan(int s1[],int s2[],int a,int b)
    {
        if(a != b)
            return false;
        for(int i=0; i<a; i++)
        {
            if(s1[i] != s2[i])
                return false;
        }
        return true;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
        //freopen("in.txt","r",stdin);
        cin>>n>>m;
        int a,b,c,d,e;
        for(int i=0; i<m; i++)
        {
            cin>>a>>b>>c>>d>>e;
            if(c == 0)
            {
                addEdge1(b,a,d,e);
                addEdge2(b,a,e,d);
            }
            addEdge1(a,b,d,e);
            addEdge2(a,b,e,d);
        }
    //    for(int i=0;i<vec1[3].size();i++)
    //        cout<<"is : "<<vec1[3][i].c<<" ";
        cin>>s>>en;
        dijkstra2();
        int ss1[maxn];
        int ss2[maxn];
        int now = en;
        int pos1 = 0,pos2 = 0;
        int dis1 = dis[en];
        while(pre[now] != -1)
        {
            ss1[pos1++] = now;
            now = pre[now];
        }
        dijkstra1();
        now = en;
        while(pre[now] != -1)
        {
            ss2[pos2++] = now;
            now = pre[now];
        }
     
     
        if(panduan(ss1,ss2,pos1,pos2))
        {
            cout<<"Time = "<<dis1<<"; ";
            cout<<"Distance = "<<dis[en]<<": ";
            cout<<s;
            for(int i=pos2-1; i>=0; i--)
                cout<<" => "<<ss2[i];
            cout<<endl;
            return 0;
        }
        cout<<"Time = "<<dis1<<": ";
        cout<<s;
        for(int i=pos1-1; i>=0; i--)
            cout<<" => "<<ss1[i];
        cout<<endl;
        cout<<"Distance = "<<dis[en]<<": ";
        cout<<s;
        for(int i=pos2-1; i>=0; i--)
            cout<<" => "<<ss2[i];
        cout<<endl;
        return 0;
    }
    
  • 相关阅读:
    采用商业智能提升企业的数字营销策略
    采用商业智能提升企业的数字营销策略
    《PostgreSQL服务器编程》一一1.3 超越简单函数
    《PostgreSQL服务器编程》一一1.3 超越简单函数
    《PostgreSQL服务器编程》一一1.3 超越简单函数
    《PostgreSQL服务器编程》一一1.3 超越简单函数
    2017 全球半导体预估跳增 11.5%,存储器最夯
    2017 全球半导体预估跳增 11.5%,存储器最夯
    如何从零学习PostgreSQL Page结构
    转成json必须是unicdoe字符
  • 原文地址:https://www.cnblogs.com/ls1272397716/p/10956185.html
Copyright © 2011-2022 走看看