一本通1527欧拉回路
1527:【例 1】欧拉回路
时间限制: 1000 ms 内存限制: 262144 KB【题目描述】
原题来自:UOJ #117
有一天一位灵魂画师画了一张图,现在要你找出欧拉回路,即在图中找一个环使得每条边都在环上出现恰好一次。
一共两个子任务:
这张图是无向图。(50 分)
这张图是有向图。(50 分)
【输入】
第一行一个整数 t,表示子任务编号。t∈{1,2},如果 t=1 则表示处理无向图的情况,如果 t=2 则表示处理有向图的情况。
第二行两个整数 n,m,表示图的结点数和边数。
接下来 m 行中,第 i 行两个整数 vi,ui ,表示第 i 条边(从 1 开始编号)。保证 1≤vi,ui≤n。
如果 t=1 则表示 vi 到 ui 有一条无向边。
如果 t=2 则表示 vi 到 ui 有一条有向边。
图中可能有重边也可能有自环。
【输出】
如果不可以一笔画,输出一行 NO。
否则,输出一行 YES,接下来一行输出一组方案。
如果 t=1,输出 m 个整数 p1,p2,…,pm 。令 e=|pi|,那么 e 表示经过的第 i 条边的编号。如果 pi为正数表示从 ve 走到 ue ,否则表示从 ue 走到 ve 。
如果 t=2,输出 m 个整数 p1,p2,…,pm 。其中 pi 表示经过的第 i 条边的编号。
【输入样例】
1
3 3
1 2
2 3
1 3
【输出样例】
YES
1 2 -3
【提示】
样例输入 2
2
5 6
2 3
2 5
3 4
1 2
4 2
5 1
样例输出 2
YES
4 1 3 5 2 6
数据范围与提示:
1≤n≤10^5,0≤m≤2×10^5
--------------------------放了一大坨概念在下面--------------------------
欧拉回路和欧拉路径的几个概念:
欧拉环:图中经过每条边一次且仅一次的环;
欧拉路径:图中经过每条边一次且仅一次的路径;
欧拉图:有至少一个欧拉环的图;
半欧拉图:没有欧拉环,但有至少一条欧拉路径的图。
【无向图】
一个无向图是欧拉图当且仅当该图是连通的(注意,不考虑图中度为0的点,因为它们的存在对于图中是否存在欧拉环、欧拉路径没有影响)且所有点的度数都是偶数;一个无向图是半欧拉图当且仅当该图是连通的且有且只有2个点的度数是奇数(此时这两个点只能作为欧拉路径的起点和终点);
证明:因为任意一个点,欧拉环(或欧拉路径)从它这里进去多少次就要出来多少次,故(进去的次数+出来的次数)为偶数,又因为(进去的次数+出来的次数)=该点的度数(根据定义),所以该点的度数为偶数。
【有向图】
一个有向图是欧拉图当且仅当该图的基图(将所有有向边变为无向边后形成的无向图,这里同样不考虑度数为0的点)是连通的且所有点的入度等于出度;一个有向图是半欧拉图当且仅当该图的基图是连通的且有且只有一个点的入度比出度少1(作为欧拉路径的起点),有且只有一个点的入度比出度多1(作为终点),其余点的入度等于出度。
证明:与无向图证明类似,一个点进去多少次就要出来多少次。
模板嘛。。。
1 /* 2 不懂为什么dfs里的i加个&可以快这么多 3 */ 4 #pragma comment(linker, "/STACK:102400000,102400000") 5 #include <bits/stdc++.h> 6 using namespace std; 7 const int N=100005,M=500005; 8 inline int read() 9 { 10 int s=0,f=0; 11 char ch=' '; 12 while(!isdigit(ch)) 13 { 14 f|=(ch=='-'); 15 ch=getchar(); 16 } 17 while(isdigit(ch)) 18 { 19 s=(s<<3)+(s<<1)+(ch^48); 20 ch=getchar(); 21 } 22 return (f)?(-s):(s); 23 } 24 #define R(x) x=read() 25 inline void write(int x) 26 { 27 if(x<0) 28 { 29 putchar('-'); 30 x=-x; 31 } 32 if(x<10) 33 { 34 putchar(x+'0'); 35 return; 36 } 37 write(x/10); 38 putchar((x%10)+'0'); 39 return; 40 } 41 inline void writeln(int x) 42 { 43 write(x); 44 putchar('\n'); 45 return; 46 } 47 #define W(x) write(x),putchar(' ') 48 #define Wl(x) writeln(x) 49 int n,m,T; 50 int Indeg[N],Outdeg[N],Deg[N]; 51 namespace Oulahuilu 52 { 53 int tot=0,Next[M],to[M],head[N]; 54 bool Arr[M]; 55 inline void add(int x,int y) 56 { 57 Next[++tot]=head[x]; 58 to[tot]=y; 59 head[x]=tot; 60 return; 61 } 62 int Huilu[M],Huilu_cnt=0; 63 inline void Run(int x) 64 { 65 for(int &i=head[x];i;i=Next[i]) if(!Arr[i]) 66 { 67 int oo=i; 68 Arr[i]=1; 69 if(T==1) 70 { 71 (i&1)?(Arr[i+1]=1):(Arr[i-1]=1); 72 } 73 Run(to[i]); 74 Huilu[++Huilu_cnt]=oo; 75 } 76 return; 77 } 78 inline void Output() 79 { 80 int i; 81 for(i=Huilu_cnt;i>=1;i--) 82 { 83 if(T==1) 84 { 85 W(((Huilu[i]&1)?1:-1)*((Huilu[i]+1)/2)); 86 } 87 else 88 { 89 W(Huilu[i]); 90 } 91 } 92 return; 93 } 94 } 95 int main() 96 { 97 // freopen("tour14.in","r",stdin); 98 // freopen("my.out","w",stdout); 99 int i; 100 R(T); 101 R(n); 102 R(m); 103 if(T==1) 104 { 105 106 for(i=1;i<=m;i++) 107 { 108 int x,y; 109 R(x); 110 R(y); 111 Deg[x]++; 112 Deg[y]++; 113 Oulahuilu::add(x,y); 114 Oulahuilu::add(y,x); 115 } 116 for(i=1;i<=n;i++) if(Deg[i]&1) 117 { 118 return 0*puts("NO"); 119 } 120 for(i=1;i<=n;i++) if(Oulahuilu::head[i]) 121 { 122 Oulahuilu::Run(i); 123 break; 124 } 125 if(Oulahuilu::Huilu_cnt!=m) 126 { 127 puts("NO"); 128 } 129 else 130 { 131 puts("YES"); 132 Oulahuilu::Output(); 133 } 134 } 135 else 136 { 137 for(i=1;i<=m;i++) 138 { 139 int x,y; 140 R(x); 141 R(y); 142 Outdeg[x]++; 143 Indeg[y]++; 144 Oulahuilu::add(x,y); 145 } 146 for(i=1;i<=n;i++) if(Indeg[i]!=Outdeg[i]) 147 { 148 return 0*puts("NO"); 149 } 150 for(i=1;i<=n;i++) if(Oulahuilu::head[i]) 151 { 152 Oulahuilu::Run(i); 153 break; 154 } 155 if(Oulahuilu::Huilu_cnt!=m) 156 { 157 puts("NO"); 158 } 159 else 160 { 161 puts("YES"); 162 Oulahuilu::Output(); 163 } 164 } 165 return 0; 166 } 167 /* 168 input 169 1 170 3 3 171 1 2 172 2 3 173 1 3 174 output 175 YES 176 1 2 -3 177 178 input 179 2 180 5 6 181 2 3 182 2 5 183 3 4 184 1 2 185 4 2 186 5 1 187 output 188 YES 189 4 1 3 5 2 6 190 191 input 192 2 193 100000 3 194 41700 41700 195 15415 31090 196 31090 15415 197 output 198 NO 199 */