UOJ117 欧拉回路[欧拉回路]

找欧拉回路的模板题。


知识点详见图连通性学习笔记。

注意一些写法上的问题。

  • line37&line61:因为引用,所以j和head值是同步更新的,类似于网络流的当前弧优化,除了优化枚举外,这样还有一个好处就是这个点所有边遍历完退回的时候,j直接就是和head一样是0,避免退回的时候枚举边,但是要注意保存原j值为tmp。。。
  • 一些特殊数据:
  • 图只有一个连通块,但有些点是孤立点。根据题意,这是可能的,所以要找到第一个有度数的点(表示在连通块里)开始dfs
  • 但是若干个块不连通的话就不行了,所以有line47判断。(不过这个判断还可以判一个连通块存不存在解)
  • 还有全是孤立点的情况也特判掉
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 #define mst(x) memset(x,0,sizeof x)
 8 #define dbg(x) cerr << #x << " = " << x <<endl
 9 #define dbg2(x,y) cerr<< #x <<" = "<< x <<"  "<< #y <<" = "<< y <<endl
10 using namespace std;
11 typedef long long ll;
12 typedef double db;
13 typedef pair<int,int> pii;
14 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
15 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
16 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;}
17 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;}
18 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
19 template<typename T>inline T read(T&x){
20     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
21     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
22 }
23 const int N=4e5+7;
24 int opt,n,m;
25 namespace task1{
26     int head[N],nxt[N],to[N],tot=1;
27     inline void add(int x,int y){
28         to[++tot]=y,nxt[tot]=head[x],head[x]=tot;
29         to[++tot]=x,nxt[tot]=head[y],head[y]=tot;
30     }
31     #define y to[j]
32     int deg[N],vis[N],stk[N],top;
33     void dfs(int x){
34         for(register int&j=head[x],tmp;j;j=nxt[j])if(!vis[j]){//dbg(j);
35             vis[j]=vis[j^1]=1,tmp=j;
36             dfs(y);//因为引用,所以j和head值是同步更新的,注意保存原j值... 
37             stk[++top]=tmp&1?-(tmp>>1):(tmp>>1);
38         }
39     }
40     #undef y
41     inline void solve(){
42         for(register int i=1,x,y;i<=m;++i)read(x),read(y),add(x,y),++deg[x],++deg[y];
43         for(register int i=1;i<=n;++i)if(deg[i]&1){puts("NO");return;}
44         int st;for(st=1;!deg[st];++st);
45         if(st>n){puts("YES");return;}
46         dfs(st);
47         if(top<m){puts("NO");return;}
48         puts("YES");
49         while(top)printf("%d%c",stk[top]," \n"[top==1]),--top;
50     }
51 }
52 namespace task2{
53     int head[N],nxt[N],to[N],tot=0;
54     inline void add(int x,int y){to[++tot]=y,nxt[tot]=head[x],head[x]=tot;}
55     int ind[N],outd[N],vis[N],stk[N],top;
56     #define y to[j]
57     void dfs(int x){
58         for(register int&j=head[x],tmp;j;j=nxt[j])if(!vis[j]){
59             vis[j]=1,tmp=j;
60             dfs(y);
61             stk[++top]=tmp;
62         }
63     }
64     #undef y
65     inline void solve(){
66         for(register int i=1,x,y;i<=m;++i)read(x),read(y),add(x,y),++outd[x],++ind[y];
67         for(register int i=1;i<=n;++i)if(ind[i]^outd[i]){puts("NO");return;}
68         int st;for(st=1;!outd[st];++st);
69         if(st>n){puts("YES");return;}
70         dfs(st);
71         if(top<m){puts("NO");return;}
72         puts("YES");
73         while(top)printf("%d%c",stk[top]," \n"[top==1]),--top;
74     }
75 }
76 
77 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
78     read(opt),read(n),read(m);
79     if(opt==1)task1::solve();
80     else task2::solve();
81     return 0;
82 }
View Code

 

posted @ 2019-10-28 19:18  Ametsuji_akiya  阅读(159)  评论(0编辑  收藏  举报