zoukankan      html  css  js  c++  java
  • 列出连通集

    题目如下:

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

    输入格式:

    输入第1行给出2个整数N(0<N10)和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 #include<iostream>
      2 #include<cstdio>
      3 #include<malloc.h>
      4 #include<queue>
      5 using namespace std;
      6 
      7 #define Null -1
      8 #define MAX 50
      9 /*构造邻接表*/
     10 int Visited[MAX];
     11 typedef struct _EdgNode{
     12     int Adjv;
     13     struct _EdgNode *Next;
     14 
     15 }EdgNode;
     16 
     17 typedef struct _VNode{
     18     //int Weight;
     19     int VN;
     20     EdgNode *first_Edg;//通过其第一条边进行下一个顶点之间连接
     21 }VNode;
     22 
     23 typedef struct _LGraph{
     24     int vexnum;
     25     int edgnum;
     26     VNode Vex[MAX];
     27 }LGraph;
     28 
     29 LGraph *PG;
     30 
     31 EdgNode * link_last(EdgNode *list,EdgNode *node)
     32 {
     33     /*由于第一条边被人所占了,说明还有其他点与此点相连接的,同时在插入可以进行排序*/
     34     //在这里排序的过程中分了两种情况第一种首地址就开始比Node小,直接用Node->next=list
     35 //第二种情况是首地址最小,在中间插入,必须要不断进行判断p->next进行判断
     36   EdgNode *p=list,*t=list;
     37   
     38     while(p!=NULL)
     39     {    
     40 if(node->Adjv<p->Adjv)
     41 {
     42 node->Next=p;
     43 list=node;
     44 return list;
     45 break;
     46 }
     47 else if( p->Next!=NULL && node->Adjv<p->Next->Adjv )
     48 {
     49 node->Next=p->Next;
     50 p->Next=node;
     51 return list;
     52 break;
     53 }
     54 else
     55 {   p->Next=node;
     56 node->Next=NULL;
     57    p=p->Next;
     58 }
     59 return list;
     60     }
     61 
     62 }
     63 
     64 LGraph *create_LGraph()
     65 {
     66     int Vex,Edg;
     67     cin>>Vex>>Edg;  //输入顶点数、边数
     68     LGraph *pG;
     69     EdgNode *ednode;
     70 
     71     pG=(LGraph*)malloc(sizeof(struct _LGraph));
     72     memset(pG,-1,sizeof(LGraph));
     73     pG->vexnum=Vex;pG->edgnum=Edg;
     74     
     75     //将点进行初始化
     76     for(int i=0;i<Vex;i++)
     77     {
     78         pG->Vex[i].VN=i;
     79         pG->Vex[i].first_Edg=NULL;
     80 
     81     }
     82 
     83     //开始输入数据
     84     int c1,c2,i,j;
     85     for (int j=0;j<Edg;j++)
     86     {    
     87         cin>>c1>>c2;
     88         ednode=(EdgNode*)malloc(sizeof(EdgNode));
     89         ednode->Adjv=c2;ednode->Next=NULL;
     90         for( i=0;i<Vex;i++)
     91         {
     92             if(c1==pG->Vex[i].VN)
     93             {  
     94                 if(pG->Vex[i].first_Edg==NULL)
     95                 {
     96                     pG->Vex[i].first_Edg=ednode;
     97                     pG->Vex[i].first_Edg->Next=NULL;
     98                 }
     99                 else
    100                 {
    101                       pG->Vex[i].first_Edg=  link_last(pG->Vex[i].first_Edg,ednode);
    102                 }
    103             }
    104             }
    105               /*-----这里只建立起来单个方向的存贮-------*/
    106         ednode=(EdgNode*)malloc(sizeof(EdgNode));
    107         ednode->Adjv=c1;ednode->Next=NULL;
    108         for( i=0;i<Vex;i++)
    109         {
    110             if(c2==pG->Vex[i].VN)
    111             {  
    112                 if(pG->Vex[i].first_Edg==NULL)
    113                 {
    114                     pG->Vex[i].first_Edg=ednode;
    115                     pG->Vex[i].first_Edg->Next=NULL;
    116                 }
    117                 else
    118                 {
    119 pG->Vex[i].first_Edg=  link_last(pG->Vex[i].first_Edg,ednode);
    120                 }
    121             }
    122             }
    123     }
    124     return pG;
    125 }
    126 void DFS(int V,EdgNode *p)
    127 { 
    128 Visited[V]=true;
    129 printf("%d",V);
    130 if(p!=NULL)
    131 {
    132 while(p!=NULL)
    133 {    
    134 if(!Visited[p->Adjv])
    135 {
    136 DFS(PG->Vex[p->Adjv].VN,PG->Vex[p->Adjv].first_Edg);
    137 }
    138 p=p->Next;
    139 }
    140 }
    141 else
    142 {
    143 
    144 return;
    145 }
    146 }
    147 
    148 void ListComponentsWithDFS( LGraph *P){
    149 for(int V=0;V<P->vexnum;V++)
    150     {
    151         if(!Visited[V])
    152         {
    153             printf("{");
    154 DFS(V,PG->Vex[V].first_Edg);
    155             printf("}");
    156         }
    157     }
    158 
    159 }
    160 queue<int>q,R;
    161 //求BFS进行的是层次遍历需要用到队列
    162 void BFS_1(int V,EdgNode *p)
    163 {
    164 while(p!=NULL)
    165 {
    166 if(Visited[p->Adjv])
    167 {
    168 p=p->Next;
    169 }
    170 else
    171 {
    172 q.push(p->Adjv);
    173 Visited[p->Adjv]=true;
    174 p=p->Next;
    175 }
    176 }
    177 
    178 }
    179 
    180 void BFS(int V,EdgNode *p)
    181 {   
    182 
    183         if(!Visited[V])
    184         {  q.push(V);
    185   Visited[V]=true;
    186 }
    187 while(!q.empty())
    188 {
    189 while(p!=NULL)
    190 {
    191  if(!Visited[p->Adjv])
    192    {   q.push(p->Adjv);
    193  Visited[p->Adjv]=true;
    194   }
    195  p=p->Next;
    196 
    197 
    198 }
    199 cout<<q.front()<<" ";
    200  q.pop();
    201  if(!q.empty())
    202  {//对其进行次级路
    203  BFS_1(PG->Vex[q.front()].VN,PG->Vex[q.front()].first_Edg);
    204  }
    205  }
    206 }
    207 
    208 void ListComponentsWithBFS( LGraph *P)
    209 {
    210 for(int V=0;V<P->vexnum;V++)
    211     {
    212         if(!Visited[V])
    213         {
    214             printf("{");
    215 BFS(V,P->Vex[V].first_Edg);//BFS采用的是层次遍历
    216             printf("}");
    217         }
    218     }
    219 
    220 
    221 }
    222     
    223 
    224 int main()
    225 {    
    226   
    227     PG=create_LGraph();
    228 //开始进行DFS遍历
    229  ListComponentsWithDFS(PG);
    230  memset(Visited,0,sizeof(Visited));
    231   ListComponentsWithBFS(PG);
    232     return 0;
    233 }

    /*------------------到了这里采用邻接链表并且是无向图,发现在做DFS递归方式很复杂-------------------------*/

    在此我想了一个办法由于从小到大的遍历,同时要用上邻接链表的形式:只要在插入时候开始进行排序对每一行的相邻顶点从小到大排序,同时可以比较一下用邻接链表和邻接矩阵之后代码的复杂度,(不够值得欣慰的是小白对代码理解度又增高了一点)

     从这里得到一个启示:编程的代码不是越复杂就越好,其实是对问题以最佳的,最简单的方式书写,解决问题才是最重要的,最简洁,最便捷手段才是编程高手所需要的素质。

    #include <cstdio>
    #include<queue>
    #include<iostream>
    #include<cstdlib>
    using namespace std;
    #define N 15
    
    void ListComponentsWithDFS();
    void ListComponentsWithBFS();
    void DFS(int V);
    void BFS(int V);
    void InitVisit(void);
    
    int n;
    bool Visited[N];//这个是个监控举证
    int G[N][N] = {0};
    
    int main()
    {
        int E;
    
        scanf("%d%d", &n, &E);
        for (int i = 0; i < E; i++)
        {
            int a, b;
            scanf("%d%d", &a, &b);
            G[b][a] = G[a][b] = 1;//在这里建立邻接矩阵的形式
        }
        ListComponentsWithDFS();
        cout<<" "<<endl;
        InitVisit();
        ListComponentsWithBFS();
    
        return 0;
    }
    
    void InitVisit()
    {
    
        for(int i=0;i<N;i++)
        {
            Visited[i]=false;
        }
    }
    void ListComponentsWithDFS(){
        for(int V=0;V<n;V++)
        {
            if(!Visited[V])
            {
                printf("{");
                DFS(V);
                printf("}");
            }
        }
    
    }
    
    void DFS(int V)
    {
        Visited[V]=true;
        printf("%d",V);
        cout<<"  ";
        for(int i=0;i<n;i++)
        {
            if(G[V][i] &&!Visited[i])
                DFS(i);
        }
    }
    
    void ListComponentsWithBFS()
    {
        for(int V=0;V<n;V++)
        {
            if(!Visited[V])
            {
                printf("{");
                BFS(V);//BFS采用的是层次遍历
                printf("}");
            }
        }
    
    
    }
        
    
    void BFS(int V)
    {    queue<int>q;
        //如果采用层次遍历必须要将其从小到大遍历,借用队列形式
        q.push(V);int c;
        Visited[V]=true;
        while(!q.empty())    
        {
            cout<<q.front()<<" ";
        
            for(int j=0;j<n;j++)
            {
                    if(G[q.front()][j] && !Visited[j])
                {
                    q.push(j);
                    Visited[j]=true;
                
            }
            
        }
                q.pop();
        }
    
    }
  • 相关阅读:
    链式表的操作
    顺序表的操作
    MDX基础
    1071 小赌怡情 (15 分)
    1069 微博转发抽奖 (20 分)
    1068 万绿丛中一点红 (20 分)
    1066 图像过滤 (15 分)
    02-线性结构2 一元多项式的乘法与加法运算 (20 分
    03-树1 树的同构 (25 分)
    03-树3 Tree Traversals Again (25 分)
  • 原文地址:https://www.cnblogs.com/woainifanfan/p/5468808.html
Copyright © 2011-2022 走看看