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 

image

参考: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();
}

 

posted @ 2026-05-26 06:52  董晓  阅读(56)  评论(0)    收藏  举报