D166 欧拉回路 P6066 [USACO05JAN] Watchcow S
D166 欧拉回路 P6066 [USACO05JAN] Watchcow S_哔哩哔哩_bilibili
P6066 [USACO05JAN] Watchcow S - 洛谷
从 1 号农场开始巡逻,每条路必须从两个方向各走恰好一遍,最后回到 1 号农场。保证这样的路径存在。如果有多条路径,任意输出一条即可。
思路
从 1 号农场开始,最后回到 1 号农场。显然是欧拉回路,
每条路必须从两个方向各走恰好一遍。即连正反有向边,然后跑有向图的欧拉回路
保证这样的路径存在。那就从 1 号点开始搜索
有多条路径,任意输出一条。排序也免了。时间复杂度为 $O(m)$
样例建图,最小字典序路径为 1 2 1 4 2 3 2 4 3 4 1

参考:D165【模板】有向图 欧拉路径 欧拉回路 P7771 欧拉路径 - 董晓 - 博客园
// 欧拉路径 欧拉回路 O(m) #include<bits/stdc++.h> using namespace std; const int N=10005; int n,m; int rd[N],cd[N]; stack<int> path; vector<int> e[N]; //邻接表 int p[N]; //p[x]初始值为0,表示点x当前处理到第几条出边,相当于全局指针,指向下一条应当处理的边 void dfs(int x){ for(int i=p[x]; i<e[x].size(); i=p[x]){ p[x]=i+1; //全局指针,指向下一条边 dfs(e[x][i]); } path.push(x); } int main(){ scanf("%d%d",&n,&m); for(int i=1,u,v;i<=m;i++){ scanf("%d%d",&u,&v); e[u].push_back(v); //邻接表连边 e[v].push_back(u); //邻接表连边 cd[u]++; rd[v]++; //累加出度,入度 cd[v]++; rd[u]++; //累加出度,入度 } // for(int i=1;i<=n;i++) sort(e[i].begin(),e[i].end()); //排序 dfs(1); while(!path.empty())printf("%d\n",path.top()),path.pop(); }
浙公网安备 33010602011771号