欧拉回路
//有向图
//欧拉回路:1.图连通2.每个点的入度等于出度//欧拉道路:1.图连通2.每个点的入度等于出度或有两个点入度不等于出度,且一个点出度比入度大一(起点),另一个点入度比出度小一(终点)如下图只能从中间一点开始到中间另一点结束,并且起点出度比入度大一
#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); //递归搜索路径 } }
欧拉道路
//有向图的欧拉道路的查找即路径打印方式与欧拉通路差不多,关键在于包含欧拉回路的情况下再考虑入度和出度相差1的情况
//有向图的欧拉道路起点必须是出度比入度大一的那个点,所以要先扫描一遍找出那两个点,如果都相等,那就参照欧拉回路的方式做,否则从该点开始路径递归
#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); //递归搜索路径 } }