• 第六章作业(1)


    7-1 列出连通集 (30 分)
     

    给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集。假设顶点从0到N1编号。进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点。

    输入格式:

    输入第1行给出2个整数N(0)和E,分别是图的顶点数和边数。随后E行,每行给出一条边的两个端点。每行中的数字之间用1空格分隔。

    输出格式:

    按照"{ v1​​ v2​​ ... vk​​ }"的格式,每行输出一个连通集。先输出DFS的结果,再输出BFS的结果。

    输入样例:

    8 6
    0 7
    0 1
    2 0
    4 1
    2 4
    3 5
    

    输出样例:

    { 0 1 4 2 7 }
    { 3 5 }
    { 6 }
    { 0 1 2 7 4 }
    { 3 5 }
    { 6 }

    根据老师日常引导的方法--我们先从主函数讲起
     1 int main()//首先先从大方向开始掌握思路,于是先打主函数 
     2 {
     3     ALGraph G; //由题知是由图来完成,那么应该先创建一张图 
     4     
     5     createUDG(g) ;// 生成图 
     6      
     7     for(int i=0;i<G.vex;i++) 
     8         sort(G,i);//根据每一个顶点进行排序,从而更好地进行匹配
     9     
    10     //排序后进行深搜+广搜
    11     
    12     //深搜     
    13     for(int i=0;i<G.vex;i++)
    14     {
    15         if(vi[i]==false)//循环输出呐~~ 
    16         {
    17             cout<<"{";
    18             DFS(G,i);
    19             cout<<"}"<<endl;
    20         }
    21     }
    22  
    23     //转变vi数组 后才能进行广搜
    24     for(int i=0;i<Max;i++)
    25         vi[i]=false;
    26         
    27     //开始进行广搜
    28     for(int i=0;i<G.vex;i++)
    29         {
    30             if(vi[i]==false)//此处类似深搜的一段代码,原因就是都是循环输出哒~ 
    31             {
    32             cout<<"{";
    33             BFS(G,i);
    34             cout<<"}"<<endl;
    35         }
    36          } 
    37     
    38 return 0;
    39 }
    View Code
     

    然后就开始一步步补充我们的主函数挖的坑啦~~

    首先是ALGraph定义

    1 typedef struct
    2 {//图的定义 
    3     int vex, arc;//图的顶点数量和边的数量 
    4     adjList vertices;//生成顶点列表  
    5 }ALGraph;
    View Code

    好的,那么我们又给自己挖了一个坑,既然是坑就得补上,AdjList邻接表类型

    1 typedef struct VNode{//顶点列表的定义 
    2     int data;//留给数据的一个空间 
    3     struct ArcNode *firstArc;//这个顶点的第一条边的指针 
    4 }VNode,AdjList[Max]; //AdjList表示邻接表类型
    View Code

    得,又挖了一个坑,但是应该是图的最后一个啦~

    1 typedef struct ArcNode{//由顶点列表推出来的边节点定义 
    2     int adjvex;//当前结点的顶点位置 
    3     struct ArcNode *nextArc;//指向下一条边的指针 
    4 }ArcNode,*L;
    View Code

    接着就是生成图的函数啦createUDG(G)~

     1 void createUDG(ALGraph &G)
     2 {
     3     cin >> G.vex >>G.arc;//输入顶点和节点 分别的总数~ 
     4     for(int i=0;i<G.vex;i++)
     5     {
     6         G.vertices[i].data = i;
     7         G.vertices[i].firstArc = NULL;
     8     }
     9     int v1,v2;//一条边的两个顶点 
    10     L p1,p2;
    11     for(int i=0;i<G.arc;i++)
    12     {
    13         cin >> v1 >> v2;//对顶点V1处理,将V2加入到链表中
    14          p1 = new ArcNode;
    15          p1 -> adjvex = v2;
    16          p1 -> nextArc = G.vertices[v1].firstArc;
    17          G.vertices[v1].firstArc = p1;
    18          
    19          //        对顶点v2处理,将v1加入到链表中 
    20         p2 = new ArcNode;
    21         p2 -> adjvex = v1;
    22         p2 -> nextArc = G.vertices[v2].firstArc;
    23         G.vertices[v2].firstArc = p2;    
    24         
    25     }
    26 }
    View Code

    接着就是排序的--采用冒泡排序。。

     1 void sort(ALGraph G,int v)
     2 {//一种冒泡排序法,对于顶点的边的点进行排序,参考了大佬的排序 
     3     L i,j;
     4     int k;
     5     for(i=G.vertices[v].firstArc;i!=NULL;i=i->nextArc)
     6         for(j=G.vertices[v].firstArc;j->nextArc!=NULL;j=j->nextArc)
     7             if(j->adjvex > j->nextArc->adjvex)
     8             {
     9                 k = j->adjvex;
    10                 j->adjvex = j->nextArc->adjvex;
    11                 j->nextArc->adjvex = k;
    12             }    
    13 }
    View Code

    那么接下来就是最后的,额,深搜与广搜了

    首先弄一个

    //判断是否访问过的数组
    bool vi[Max] = {false};

    接着就是深搜了:

     1 //开始深搜的函数
     2 void(ALGrap G,int v) 
     3  {
     4      //访问当前的结点
     5      cout<<" "<<v;
     6      vi[v] = true;
     7      L p;//与顶点连接的下一个边
     8      
     9      int w;//与顶点连接的下一个点
    10      
    11      p = G.vertices.firstArc; 
    12      while(p!=NULL)
    13      {//取得这一条边连接的点,看看是否已经被访问过 
    14          w = p->adjvex;
    15          if(!vi[w])
    16              DFS(G,w);
    17         p = p->nextArc; 
    18      }
    19  }
    View Code

    接着就是广搜了

     1  //广度搜索
     2 void BFS(ALGraph G, int v)
     3 {//队列q,u用作存储出队的元素的下标
     4     queue<int> q;
     5     int u;
     6     //访问顶点
     7     cout<<" "<<v;
     8     vi[v] = true;
     9     //入队
    10     q.push(v);
    11     while(!=q.empty())
    12     {
    13         u = q.front();
    14         q.pop();
    15         
    16         //for 循环, 进行出队元素的所有的边的点访问,入队
    17         for(L p=G.vertices[u].firstArc; p!=NULL ; p=p->nextArc)
    18         {//对于出队的点,判断是否有邻接点,有就访问,然后入队
    19             if(!vi[p->adjvex])
    20             {
    21                 cout<<" "<<p->adjvex;
    22                 vi[p->adjvex] = true;
    23                 q.push(p->adjvex);
    24              } 
    25             
    26          } 
    27      } 
    28     
    29  } 
    View Code

    就这样就整个就完成啦~~

    可惜就是通不过.........

    还是需要修改,格式错误---记录一篇错误的博客。

     下面才是真正的全部代码:

      1 #include<iostream>
      2 #include <queue>
      3 #define Max 20 //最大顶点数
      4 using namespace std;
      5 
      6 
      7 typedef struct ArcNode{//由顶点列表推出来的边节点定义 
      8     int adjvex;//当前结点的顶点位置 
      9     struct ArcNode *nextArc;//指向下一条边的指针 
     10 }ArcNode,*L;
     11 
     12 typedef struct VNode{//顶点列表的定义 
     13     int data;//留给数据的一个空间 
     14     struct ArcNode *firstArc;//这个顶点的第一条边的指针 
     15 }VNode,AdjList[Max]; //AdjList表示邻接表类型
     16 
     17 typedef struct{//图的定义 
     18     int vex, arc;//图的顶点数量和边的数量 
     19     AdjList vertices;//生成顶点列表  
     20 }ALGraph;
     21 
     22 void createUDG(ALGraph &G)
     23 {
     24     cin >> G.vex >>G.arc;//输入顶点和节点 分别的总数~ 
     25     for(int i=0;i<G.vex;i++)
     26     {
     27         G.vertices[i].data = i;
     28         G.vertices[i].firstArc = NULL;
     29     }
     30     int v1,v2;//一条边的两个顶点 
     31     L p1,p2;
     32     for(int i=0;i<G.arc;i++)
     33     {
     34         cin >> v1 >> v2;//对顶点V1处理,将V2加入到链表中
     35          p1 = new ArcNode;
     36          p1 -> adjvex = v2;
     37          p1 -> nextArc = G.vertices[v1].firstArc;
     38          G.vertices[v1].firstArc = p1;
     39          
     40          //        对顶点v2处理,将v1加入到链表中 
     41         p2 = new ArcNode;
     42         p2 -> adjvex = v1;
     43         p2 -> nextArc = G.vertices[v2].firstArc;
     44         G.vertices[v2].firstArc = p2;    
     45         
     46     }
     47 }
     48 
     49 void sort(ALGraph G,int v)
     50 {//一种冒泡排序法,对于顶点的边的点进行排序,参考了大佬的排序 
     51     L i,j;
     52     int k;
     53     for(i=G.vertices[v].firstArc;i!=NULL;i=i->nextArc)
     54         for(j=G.vertices[v].firstArc;j->nextArc!=NULL;j=j->nextArc)
     55             if(j->adjvex > j->nextArc->adjvex)
     56             {
     57                 k = j->adjvex;
     58                 j->adjvex = j->nextArc->adjvex;
     59                 j->nextArc->adjvex = k;
     60             }    
     61 }
     62 
     63 //判断是否访问过的数组 
     64 bool vi[Max] = {false};
     65 
     66 //开始深搜的函数
     67 void DFS(ALGraph G,int v) 
     68  {
     69      //访问当前的结点
     70      cout<<" "<<v;
     71      vi[v] = true;
     72      L p;//与顶点连接的下一个边
     73      
     74      int w;//与顶点连接的下一个点
     75      
     76      p = G.vertices[v].firstArc; 
     77      while(p!=NULL)
     78      {//取得这一条边连接的点,看看是否已经被访问过 
     79          w = p->adjvex;
     80          if(!vi[w])
     81              DFS(G,w);
     82         p = p->nextArc; 
     83      }
     84  }
     85  
     86  //广度搜索
     87 void BFS(ALGraph G, int v)
     88 {//队列q,u用作存储出队的元素的下标
     89     queue<int> q;
     90     int u;
     91     //访问顶点
     92     cout<<" "<< v;
     93     vi[v] = true;
     94     //入队
     95     q.push(v);
     96     while(!q.empty())
     97     {
     98         u = q.front();
     99         q.pop();
    100         
    101         //for 循环, 进行出队元素的所有的边的点访问,入队
    102         for(L p=G.vertices[u].firstArc; p!=NULL ; p=p->nextArc)
    103         {//对于出队的点,判断是否有邻接点,有就访问,然后入队
    104             if(!vi[p->adjvex])
    105             {
    106                 cout<<" "<<p->adjvex;
    107                 vi[p->adjvex] = true;
    108                 q.push(p->adjvex);
    109              } 
    110             
    111          } 
    112      } 
    113     
    114  } 
    115  
    116 
    117 int main()//首先先从大方向开始掌握思路,于是先打主函数 
    118 {
    119     ALGraph G; //由题知是由图来完成,那么应该先创建一张图 
    120     
    121     createUDG(G) ;// 生成图 
    122      
    123     for(int i=0;i<G.vex;i++) 
    124         sort(G,i);//根据每一个顶点进行排序,从而更好地进行匹配
    125     
    126     //排序后进行深搜+广搜
    127     
    128     //深搜     
    129     for(int i=0;i<G.vex;i++)
    130     {
    131         if(vi[i]==false)//循环输出呐~~ 
    132         {
    133             cout<<"{";
    134             DFS(G,i);
    135             cout<<" "<<"}"<<endl;
    136         }
    137     }
    138  
    139     //转变vi数组 后才能进行广搜
    140     for(int i=0;i<Max;i++)
    141         vi[i]=false;
    142         
    143     //开始进行广搜
    144     for(int i=0;i<G.vex;i++)
    145         {
    146             if(vi[i]==false)//此处类似深搜的一段代码,原因就是都是循环输出哒~ 
    147             {
    148             cout<<"{";
    149             BFS(G,i);
    150             cout<<" "<<"}"<<endl;
    151         }
    152          } 
    153     
    154 return 0;
    155 }
    View Code

    我真棒!

     
  • 相关阅读:
    [NOIp pj 2007][Luogu P1095] 守望者的逃离
    [Noip 2009 普及组 T4] [Luogu P1070] 道路游戏
    跟风Manacher算法整理
    Luogu P2569 [SCOI2010] 股票交易
    qbzt2020五一DAY1T1集合——题解
    Cena使用教程
    2020.4.15校内测试
    康托展开学习笔记
    qbzt网格图路径问题——题解
    2-sat基础详解
  • 原文地址:https://www.cnblogs.com/JeffKing11/p/10923481.html
Copyright © 2020-2023  润新知