图论 - 欧拉路径与欧拉回路
申必的SI120刚好讲到这里,于是回去复习了一下板子。
*知识点部分待补
2.习题
P2731 [USACO3.3] 骑马修栅栏 Riding the Fences
求字典序最小的无向图欧拉路径,图中有孤立点,但保证去掉孤立点的图联通。
const int N=1E3+5; int n, m; vector<int> G[N]; int deg[N], mp[N][N], nxt[N]; //nxt下一个遍历到的边 int st[N*8], t; void dfs_Euler(int x) //Hierholzer 算法 { for(int i=nxt[x]; i<(int)G[x].size(); i=nxt[x]) { nxt[x]=i+1; //边能走则走这条边往下探 if(mp[x][G[x][i]]) { --mp[x][G[x][i]], --mp[G[x][i]][x];//删边 dfs_Euler(G[x][i]); } } //何时回溯?所有边都走不了了 st[++t]=x; //回溯的过程就是将回路不断加入路径的过程 } inline int Solve() { #ifdef DEBUG printf("Debuging...\n"); #endif n=500, m=read(); for(int i=1; i<=m; i++) { int u=read(), v=read(); G[u].push_back(v), ++deg[u]; G[v].push_back(u), ++deg[v]; ++mp[u][v], ++mp[v][u]; } //判定+确定起终点 bool flag=true; int in=-1, out=-1, min_v=-1; for(int i=1;flag && i<=n;i++) { if(min_v==-1 && deg[i]) min_v=i; if(deg[i]&1) { if(in==-1) in=i; else if(out==-1) out=i; else flag=false; } } if(in==-1 && out==-1) in=out=min_v; if(!flag) return printf("No\n"); //获得字典序最小的路径 for(int i=1; i<=n; i++) sort(G[i].begin(), G[i].end()); dfs_Euler(in); for(int i=t; i; i--) printf("%d\n", st[i]); putchar('\n'); return 0; }
P7771 【模板】欧拉路径
求字典序最小的有向图欧拉路径,保证图弱联通。
int n, m; vector<int> G[N]; int ideg[N], odeg[N], nxt[N]; //mp[N][N] //nxt下一个遍历到的边 int st[N*8], t; void dfs_Euler(int x) //Hierholzer 算法 { for(int i=nxt[x]; i<(int)G[x].size(); i=nxt[x]) { nxt[x]=i+1; //边能走则走这条边往下探 //删边: 往后面的边找就是删掉前面的边了 // 有向图也不用根据方向查重 dfs_Euler(G[x][i]); } //何时回溯?所有边都走不了了 st[++t]=x; //回溯的过程就是将回路不断加入路径的过程 } inline int Solve() { #ifdef DEBUG printf("Debuging...\n"); #endif n=read(), m=read(); for(int i=1; i<=m; i++) { int u=read(), v=read(); G[u].push_back(v); ++ideg[v], ++odeg[u]; } //判定+确定起终点 bool flag=true; int in=-1, out=-1, min_v=-1; for(int i=1;flag && i<=n;i++) { if(odeg[i]==ideg[i]) { if(min_v==-1 && ideg[i]) min_v=i; } else if(odeg[i]==ideg[i]+1) { if(in==-1) in=i; else flag=false; } else if(odeg[i]+1==ideg[i]) { if(out==-1) out=i; else flag=false; } else flag=false; } if(in==-1 && out==-1) in=out=min_v; //else if(in==-1 || out==-1) flag=false; if(!flag) return printf("No\n"); //获得字典序最小的路径 for(int i=1; i<=n; i++) sort(G[i].begin(), G[i].end()); dfs_Euler(in); for(int i=t; i; i--) printf("%d ", st[i]); putchar('\n'); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探