求图中欧拉回路数量

问题描述:输入点数n、边数m、每条边连接的两个点a,b,求此无向图中不包括一个点本身的欧拉回路数量,重复不计;

解决此问题,则需要在深搜的基础上判断新搜出的欧拉回路是否已经被走过,可以利用搜索时所打的标记来判断;

使用邻接表,需要注意在无向图中连接两点有两条边,要同时考虑;

以下为代码:



#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,cnt[105],ct,qd,t,ld[205];
bool b[205],lu[105][205],qdf=0;
struct N{
  int hd;int to;int next;
}edge[205];
void add(int x,int y)
{
  ct++;
  edge[ct].to=y;
  edge[ct].hd=x;
  edge[ct].next=cnt[x];
  cnt[x]=ct;
}
void pd()
{
  t++;
  memcpy(lu[t],b,sizeof lu[t]);
  for(int i=1;i<t;i++)
  {
    bool fl=0;
    for(int j=1;j<=m*2;j++)
    if(lu[i][j]!=lu[t][j])fl=1;
    if(!fl)//若完全相同,撤销该路 
    {
      memset(lu[t],0,sizeof lu[t]);
      t--;
      break;
    } 
  }
}
void dfs(int k)
{
  if(k==qd&&!qdf)
  {
    pd();return;
  }
  qdf=0;
  for(int i=cnt[k];i>0;i=edge[i].next)
  {
    if(b[i])continue;//边 
    b[i]=1;b[ld[i]]=1;
    dfs(edge[i].to);
    b[i]=0;b[ld[i]]=0;
  }
}
int main()
{
  scanf("%d%d",&n,&m);
  for(int i=1;i<=m;i++)
  {
    int a,b;
    scanf("%d%d",&a,&b);
    add(a,b);
    ld[ct]=ct+1;
    add(b,a);
    ld[ct]=ct-1;
  }
  for(int i=1;i<=n;i++)
  {
    memset(b,0,sizeof b);
    qd=i;qdf=1;
    dfs(i);
  }
  printf("%d",t);
  return 0;
}



样例

输入

13 16
1 2
2 3
3 4
4 1
2 8
8 9
9 10
10 2
3 11
11 12
12 13
13 3
4 7
7 6
6 5
5 4

输出

11

时间: 2024-10-28 23:10:04

求图中欧拉回路数量的相关文章

poj 3895 Cycles of Lanes 修改tarjan算法求图中最大环

题意: 给一个边权均为1的无向图,求图中的最大环. 分析: tarjan算法一般用来强连通分量,它依次访问图中的各个强连通分量,这题要求最大环,而环也是强连通分量的一部分,所以可以在每个点访问其他点时修改时间戳,达到每个环上时间戳连续的目的,这样当访问到一个栈中节点时就能直接更新最大环了.根据同样的思路,即使边权任意,也可求最大环或最小环. 代码: //poj 3895 //sep9 #include <iostream> #include <vector> #include &l

Floyd-Warshall求图中任意两点的最短路径

原创 除了DFS和BFS求图中最短路径的方法,算法Floyd-Warshall也可以求图中任意两点的最短路径. 从图中任取两点A.B,A到B的最短路径无非只有两种情况: 1:A直接到B这条路径即是最短路径(前提是存在此路径): 2:A先通过其他点,再由其他点到B. 我们并不知道A是否需要通过其他点间接到达B,所以只能比较,用A到B的直接路径和A先通过其他点 再间接到达B的路径长度进行比较,然后更新为较小值. 上图中若要求顶点4到顶点3的最短路径,可以比较顶点4直接到3的路径和顶点4先到1,再到3

[hdu2460]network(依次连边并询问图中割边数量) tarjan边双联通分量+lca

题意: 给定一个n个点m条边的无向图,q个操作,每个操作给(x,y)连边并询问此时图中的割边有多少条.(连上的边会一直存在) n<=1e5,m<=2*10^5,q<=1e3,多组数据. 题解: 用tarjan求边双连通分量并缩点,缩点后组成一棵树,记录此时割边共有sum条. 连接(x,y),设c[i]为缩点后i所在的新点(边双连通分量),则c[x]-->lca-->c[y]形成一个环,环上的所有边都不再是割边,走一遍并标记,如果遇到没标记过的就sum--. 1 #includ

求图中某点到另一点的通路

图的搜索方法有DFS和BFS,但是这两个算法不能直接得到(其实是我不会)图中任意一点到另外一点的通路路径,以图中某个点作为起点,另外一点作为终点,从终点开始,利用邻接表,从后向前查找,首先查找可以直接到终点的节点,放入集合S1中,然后再查找可以直接到S1的节点,存入集合S2,只到找到起点为止.代码如下: 1 public static void getReachableNodeCollection(){ 2 ArrayList<ArrayList<Integer>> reachab

求水洼的问题(或者是说求图中连通子图的个数)----深度优先算法

遇到这个题的时候,不太容易快速的想到思路:可能会比较容易想到使用递归的思想:但是具体怎么写呢?其实这个题就相当于是图论中的求连通图,很容易应该想到的是深度优先搜索或者是广度优先搜索:我们就用深度优先算法来求这个题目:直接求有几个区域不好求,那么我们换个思路来求,这种题就是这样,直接求不好求,但是当我们转换一下思路之后就豁然开朗: 我们遍历所有的点,当遇到有水的点时,就将它周围的(八个方向)所有的水点都消除:所以在主遍历for循环中遇到几个水点就是有几个水洼: /*****************

poj The Settlers of Catan( 求图中的最长路 小数据量 暴力dfs搜索(递归回溯))

The Settlers of Catan Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1123   Accepted: 732 Description Within Settlers of Catan, the 1995 German game of the year, players attempt to dominate an island by building roads, settlements and c

POJ 1637 混合图的欧拉回路判定

题意:一张混合图,判断是否存在欧拉回路. 分析参考: 混合图(既有有向边又有无向边的图)中欧拉环.欧拉路径的判定需要借助网络流! (1)欧拉环的判定:一开始当然是判断原图的基图是否连通,若不连通则一定不存在欧拉环或欧拉路径(不考虑度数为0的点). 其实,难点在于图中的无向边,需要对所有的无向边定向(指定一个方向,使之变为有向边),使整个图变成一个有向欧拉图(或有向半欧拉图).若存在一个定向满足此条件,则原图是欧拉图(或半欧拉图)否则不是.关键就是如何定向? 首先给原图中的每条无向边随便指定一个方

在图中寻找最短路径-----深度优先算法C++实现

求从图中的任意一点(起点)到另一点(终点)的最短路径,最短距离: 图中有数字的点表示为图中的不同海拔的高地,不能通过:没有数字的点表示海拔为0,为平地可以通过: 这个是典型的求图中两点的最短路径:本例,用深度优先算法来实现: 在每一个点都有四个方向(有的点的有些方向不能通过),所以在每一个点处要处理四种方向的情况: 深度优先算法函数怎么写? 也就是写递归函数...但是递归函数肿么写??? 第一:判断初始态,从起点出发,刚开始步数为0:dfs(start_x, start_y, 0); 第二:从起

[Python] 弗洛伊德(Floyd)算法求图的直径并记录路径

相关概念 对于一个图G=(V, E),求图中两点u, v间最短路径长度,称为图的最短路径问题.最短路径中最长的称为图的直径. 其中,求图中确定的某两点的最短路径算法,称为单源最短路径算法.求图中任意两点间的最短路径算法,称为多源最短路径算法. 常用的路径算法有: Dijkstra算法 SPFA算法\Bellman-Ford算法 Floyd算法\Floyd-Warshall算法 Johnson算法 其中最经典的是Dijkstra算法和Floyd算法.Floyd算法是多源最短路径算法,可以直接求出图