Algorithm 遍历euler回路中的所有边和打印节点

Algorithm 遍历euler回路中的所有边和打印节点,algorithm,data-structures,graph,graph-algorithm,Algorithm,Data Structures,Graph,Graph Algorithm,我正在努力解决这个问题。 我可以通过观察给定结构是否可以形成euler回路来找到,但我无法找出如何找到给定测试用例的所有路径 五, 2.1 2.2 34 3.1 2 4 在节点2的电路中有一个循环,我不知道如何跟踪,如果我使用邻接列表表示,那么我将得到以下列表 1:2,3 2:1,2,2,4 3:1,4 4:2,3 所以,如何遍历每一条边,我知道这是欧拉回路的问题,但自循环的事情让我很难编写代码,我没有从任何教程或博客中了解这件事 我再次考虑过在遍历路径后从邻接列表中删除节点(为了维护euler

我正在努力解决这个问题。 我可以通过观察给定结构是否可以形成euler回路来找到,但我无法找出如何找到给定测试用例的所有路径

五,

2.1

2.2

34

3.1

2 4

在节点2的电路中有一个循环,我不知道如何跟踪,如果我使用邻接列表表示,那么我将得到以下列表

1:2,3

2:1,2,2,4

3:1,4

4:2,3

所以,如何遍历每一条边,我知道这是欧拉回路的问题,但自循环的事情让我很难编写代码,我没有从任何教程或博客中了解这件事

我再次考虑过在遍历路径后从邻接列表中删除节点(为了维护euler的属性(路径应该遍历一次)),但我使用vector存储邻接列表,我不知道如何从vector中删除特定元素。我在谷歌上搜索了一下,找到了要从向量中删除的
remove
命令,但是
remove
从向量中删除了所有匹配的元素

我现在试图解决以下问题,但得到了WA:(

#包括
#包括
#包括
int G[52][52];;
int[52],n;
void printadj(){
int i,j;

对于(i=0;i你需要做的是形成任意循环,然后将所有循环连接在一起。你似乎只做了一次深度优先遍历,这可能会给你一个欧拉回路,但也可能给你一个欧拉回路的“捷径”。这是因为在欧拉回路经过多次的每个顶点上(即,当深度优先遍历第一次到达该处时,它可以拾取直接返回深度优先遍历起点的边

因此,您的算法应该由两部分组成:

  • 查找所有周期
  • 将循环连接在一起
  • 如果操作正确,您甚至不必检查所有顶点的阶数是否为偶数,相反,您可以依赖这样一个事实:如果步骤1或2无法继续,则不存在欧拉循环

    参考实现(Java) 由于您的问题中没有语言标记,我假设我给您一个Java参考实现对您来说很好。此外,我将使用术语“node”而不是“vertex”,但这只是个人偏好(它提供了较短的代码;))

    我将在该算法中使用一个常量,我将从其他类中引用该常量:

    公共静态最终整数节点数=50;
    
    然后,我们需要一个Edge类来轻松构建循环,循环基本上是边的链接列表:

    公共类边缘
    {
    INTU,v;
    边缘上一个,下一个;
    公共边缘(int u,int v)
    {
    这个。u=u;
    这个,v=v;
    }
    /**
    *将新边附加到此边,从而指向给定节点
    *并返回新创建的边
    *附加的边开始不需要指定,因为它会指定
    *始终是此边结束的节点。
    * 
    *@param node附加边结束的节点。
    */
    公共边缘附加(int节点)
    {
    next=新边(此.v,节点);
    next.prev=这个;
    下一步返回;
    }
    }
    
    然后,我们需要一个可以轻松连接两个循环的Cycle类:

    公共类循环
    {
    边缘启动;
    boolean[]used=新的boolean[节点数+1];
    公共自行车(边缘起步)
    {
    //存储循环本身
    this.start=start;
    //并记住此循环中使用的节点
    使用的[start.u]=true;
    对于(边e=start.next;e!=start;e=e.next)
    已用[e.u]=真;
    }
    /**
    *检查此循环是否可以与给定的循环联接。即
    *当且仅当两个循环使用公共节点时的情况。
    * 
    *@return{@code true}如果这个循环和那个循环可以合并,
    *{@code false}否则。
    */
    公共布尔canJoin(循环)
    {
    //查找常用节点
    对于(int节点=1;节点1)
    {
    //将最后一个周期与之前的任何一个周期合并
    Cycle last=cycles.removeLast();
    对于(周期电流:周期)
    if(当前可加入(最后一个))
    {
    //找到一个!只需加入它并继续合并
    当前连接(最后);
    继续合并;
    }
    //没有找到兼容的循环,这意味着没有欧拉循环
    返回null;
    }
    返回cycles.getFirst();
    }
    
    你需要做的是形成任意循环,然后将所有循环连接在一起。你似乎只做了一次深度优先遍历,这可能会给你一个欧拉回路,但也可能给你一个欧拉回路的“捷径”。这是因为在欧拉回路经过多次的每个顶点上(即,当深度优先遍历第一次到达该处时,它可以拾取直接返回深度优先遍历起点的边

    因此,您的算法应该由两部分组成:

  • 查找所有周期
  • 将循环连接在一起
  • 如果操作正确,您甚至不必检查所有顶点的阶数是否为偶数,相反,您可以依赖这样一个事实:如果步骤1或2无法继续,则不存在欧拉循环

    参考实现(Java) 由于您的问题中没有语言标记,我假设我给您一个Java参考实现对您来说很好。此外,我将使用术语“node”而不是“vertex”,但这只是个人偏好(它提供了较短的代码;))

    我将在该算法中使用一个常量,我将从其他类中引用该常量:

    公共静态最终整数节点数=50;
    
    那么,我们需要一个Edg
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    int G[52][52];
    int visited[52],n;
    
    void printadj() {
      int i,j;
      for(i=0;i<51;i++) {
        for(j=0;j<51;j++)
          printf("%d  ",G[i][j]);
        printf("\n");
      }     
     }
    
     void dfs(int u){
      int v;
      for(v=0;v<51;v++){
        if(G[u][v]){
            G[u][v]--;
            G[v][u]--;
            printf("%d %d\n",u,v);       
            dfs(v);
         }                  
      }
    }
    
    bool is_euler(){
       int i,j,colsum=0,count=0;
       for(i=0;i<51;i++) {
        colsum=0;
        for(j=0;j<51;j++) {
           if(G[i][j] > 0) {
               colsum+=G[i][j];
           }
        }
         if(colsum%2!=0) count++; 
      }     
    //  printf("\ncount=%d\n",count);
      if(count >0 ) return false;
      else return true;
    }
    void reset(){
        int i,j;
        for(i=0;i<51;i++)
          for(j=0;j<51;j++)                 
            G[i][j]=0;
    }
    int main(){
        int  u,v,i,t,k;
        scanf("%d",&t);
        for(k=0;k<t;k++) {
          scanf("%d",&n);
          reset();
          for(i=0;i<n;i++){
            scanf("%d%d",&u,&v);
            G[u][v]++;
            G[v][u]++;     
           }
    //    printadj();
           printf("Case #%d\n",k+1);
          if(is_euler()) {
             dfs(u);
          }
          else printf("some beads may be lost\n");
          printf("\n");
      }
      return 0;
    }
    
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    #define max 51
    
    int G[max][max],print_u[max],print_v[max],nodes_traversed[max],nodes_found[max];
    int n,m;
    
    void printadj() {
      int i,j;
      for(i=0;i<max;i++) {
        for(j=0;j<max;j++)
          printf("%d  ",G[i][j]);
        printf("\n");
      }
     }
    
    void dfs(int u){
      int v;
      for(v=0;v<50;v++){
        if(G[u][v]){
            G[u][v]--;
            G[v][u]--;
            print_u[m]=u;
            print_v[m]=v;
            m++;
            dfs(v);
         }
      }
      nodes_traversed[u]=1;
    }
    
    bool is_evendeg(){
       int i,j,colsum=0,count=0;
       for(i=0;i<50;i++) {
        colsum=0;
        for(j=0;j<50;j++) {
           if(G[i][j] > 0) {
               colsum+=G[i][j];
           }
        }
         if(colsum&1) return false;
      }
      return true;
    }
    
    int count_vertices(int nodes[]){
     int i,count=0;
     for(i=0;i<51;i++) if(nodes[i]==1) count++;
     return count;
    }
    void reset(){
        int i,j;
        m=0;
        for(i=0;i<max;i++)
          for(j=0;j<max;j++)
            G[i][j]=0;
        memset(print_u,0,sizeof(print_u));
        memset(print_v,0,sizeof(print_v));
        memset(nodes_traversed,0,sizeof(nodes_traversed));
        memset(nodes_found,0,sizeof(nodes_found));
    }
    
    bool is_connected(int tot_nodes,int trav_nodes) {
     if(tot_nodes == trav_nodes) return true;
     else return false;
    }
    
    int main(){
        int  u,v,i,t,k,tot_nodes,trav_nodes;
        scanf("%d",&t);
        for(k=0;k<t;k++) {
          scanf("%d",&n);
          reset();
          for(i=0;i<n;i++){
            scanf("%d%d",&u,&v);
            G[u][v]++;
            G[v][u]++;
            nodes_found[u]=nodes_found[v]=1;
           }
    //    printadj();
          printf("Case #%d\n",k+1);
          tot_nodes=count_vertices(nodes_found);
          if(is_evendeg()) {
            dfs(u);
            trav_nodes=count_vertices(nodes_traversed);
            if(is_connected(tot_nodes,trav_nodes)) {
              for(i=0;i<m;i++)
                printf("%d  %d\n",print_u[i],print_v[i]);
            }
            else printf("some beads may be lost\n");
          }
          else printf("some beads may be lost\n");
          printf("\n");
      }
      return 0;
    }