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 }