有向图的欧拉回路及欧拉道路
2015-08-02 19:57
344 查看
欧拉回路
//有向图
//欧拉回路:1.图连通2.每个点的入度等于出度
//欧拉道路:1.图连通2.每个点的入度等于出度或有两个点入度不等于出度,且一个点出度比入度大一(起点),另一个点入度比出度小一(终点)如下图只能从中间一点开始到中间另一点结束,并且起点出度比入度大一
//程序本身并不复杂,无非是将无向图中对于度数的判断奇偶改为判断入度和出度是否相等
//保存路径时需要注意一点,ans数组是保存的两点,而不是一点是否被访问过(这与图的遍历不同,我一开始就错这),因为欧拉回路是可能重复经过某一点的
欧拉道路
//有向图的欧拉道路的查找即路径打印方式与欧拉通路差不多,关键在于包含欧拉回路的情况下再考虑入度和出度相差1的情况
//有向图的欧拉道路起点必须是出度比入度大一的那个点,所以要先扫描一遍找出那两个点,如果都相等,那就参照欧拉回路的方式做,否则从该点开始路径递归
//有向图
//欧拉回路:1.图连通2.每个点的入度等于出度
//欧拉道路:1.图连通2.每个点的入度等于出度或有两个点入度不等于出度,且一个点出度比入度大一(起点),另一个点入度比出度小一(终点)如下图只能从中间一点开始到中间另一点结束,并且起点出度比入度大一
//程序本身并不复杂,无非是将无向图中对于度数的判断奇偶改为判断入度和出度是否相等
//保存路径时需要注意一点,ans数组是保存的两点,而不是一点是否被访问过(这与图的遍历不同,我一开始就错这),因为欧拉回路是可能重复经过某一点的
#include <cstdio> #include <iostream> #include <queue> using namespace std; int n; int a[101][101]; int indegree[101]; int outdegree[101]; int bfs(); int ans[101][101]; int compare(); void print(int i); int main() { int m,i,j,c,d; scanf("%d%d",&n,&m); for (i=1;i<=m;i++) { scanf("%d%d",&c,&d); a[c][d]=1; outdegree[c]++;//c的出度加一 indegree[d]++;//d的入度加一 } if (!bfs())//如果图本身不连通 printf("No\n"); else if (compare())//如果入度等于出度 { printf("Yes\n"); printf("路径为:\n"); print(1); } else printf("No\n"); return 0; } int bfs() { queue<int>q; int i; int vis[101],temp;//标记是否访问过 for (i=1;i<=n;i++) vis[i]=0; q.push(1); vis[1]=1; while(!q.empty()) { temp=q.front(); q.pop(); for (i=1;i<=n;i++) if ((a[temp][i])&&(!vis[i])) { vis[i]=1; q.push(i); } } for (i=1;i<=n;i++) if (!vis[i]) { printf("%d\n",i); return 0; } return 1; } int compare() { int i; for (i=1;i<=n;i++) if (indegree[i]!=outdegree[i]) return 0; return 1; } void print(int i) { int v; for (v=1;v<=n;v++) if ((a[i][v])&&(!ans[i][v])) { ans[i][v]=1; printf("%d->%d\n",i,v); print(v); //递归搜索路径 } }
//有向图的欧拉道路起点必须是出度比入度大一的那个点,所以要先扫描一遍找出那两个点,如果都相等,那就参照欧拉回路的方式做,否则从该点开始路径递归
#include <cstdio> #include <iostream> #include <queue> #include <cmath> using namespace std; int n; int a[101][101]; int indegree[101]; int outdegree[101]; int bfs(); int x[3]; int ans[101][101]; int compare(); void print(int i); int main() { int m,i,j,c,d; scanf("%d%d",&n,&m); x[1]=0; for (i=1;i<=m;i++) { scanf("%d%d",&c,&d); a[c][d]=1; outdegree[c]++;//c的出度加一 indegree[d]++;//d的入度加一 } if (!bfs())//如果图本身不连通 printf("No\n"); else if (compare())//如果入度等于出度 { printf("Yes\n"); printf("路径为:\n"); if (!x[1])//如果是欧拉回路,那么哪一点开始都无所谓 print(1); else if (outdegree[x[1]]>outdegree[x[2]])//如果a[1]的出度大,那他就是起点 print(x[1]); else print(x[2]); } else printf("No\n"); return 0; } int bfs() { queue<int>q; int i; int vis[101],temp;//标记是否访问过 for (i=1;i<=n;i++) vis[i]=0; q.push(1); vis[1]=1; while(!q.empty()) { temp=q.front(); q.pop(); for (i=1;i<=n;i++) if ((a[temp][i])&&(!vis[i])) { vis[i]=1; q.push(i); } } for (i=1;i<=n;i++) if (!vis[i]) { printf("%d\n",i); return 0; } return 1; } int compare() { int i,ok; ok=0; for (i=1;i<=n;i++) if (indegree[i]!=outdegree[i]) { ok++; if (ok>2)return 0;//如果入度出度不相等的节点数大于2,那肯定不是欧拉道路 else x[ok]=i; } if (!ok)//如果入度都等于出度,那么是欧拉回路,自然是欧拉通路 return 1; if (fabs(indegree[x[1]]-indegree[x[2]])!=1)//如果入度相差不是1,那也不是欧拉回路 return 0; } void print(int i) { int v; for (v=1;v<=n;v++) if ((a[i][v])&&(!ans[i][v])) { ans[i][v]=1; printf("%d->%d\n",i,v); print(v); //递归搜索路径 } }
相关文章推荐
- java中的I/O流
- Nutch2.2.1 开发环境搭建
- javascript设计模式之Mediator(中介者)模式
- WRL 类库项目模板
- BFS POJ 3126 Prime Path
- SSH学习九 依赖注入及加载Spring配置文件的方法
- 20150802-泛型
- 【转】CAD2012打开自动关闭解决方法
- How to write a good tech blog
- C语言-递归算法以及经典递归(Hanoi)
- 字符串拷贝操作
- Save the Trees
- poj 3662 二分+最短路
- 输入一行字符串,找出其中的相同且长度最长的字符串
- java中怎样在界面中显示图片?
- 使用js编写一个计算器
- NGUI-实例化问题
- Javascript-基础知识(4)
- Quotient Polynomial
- HDU1224 Free DIY Tour(spfa+记录路径)