Tourists in Mancunia
找欧拉回路。
$wiki$中说
连通的无向图 有欧拉路径的充要条件是:中奇顶点(连接的边数量为奇数的顶点)的数目等于0或者2。
连通的无向图 是欧拉环(存在欧拉回路)的充要条件是:中每个顶点的度都是偶数。
算法的实现:咱删除每条经过的边就行了。
1 #include<bitset> 2 #include<set> 3 #include<cstdio> 4 #include<vector> 5 #include<iostream> 6 #define pb push_back 7 using namespace std; 8 inline char nc() { 9 return getchar(); 10 static char b[1<<16],*s=b,*t=b; 11 return s==t&&(t=(s=b)+fread(b,1,1<<16,stdin),s==t)?-1:*s++; 12 } 13 inline void read(int &x) { 14 char b = nc(); x = 0; 15 for (; !isdigit(b); b = nc()); 16 for (; isdigit(b); b = nc()) x = x * 10 + b - '0'; 17 } 18 const int N = 100010; 19 int n, m, in[N], ecnt, fa[N]; 20 struct Edge { 21 int u, v; 22 } E[200010]; 23 set < int > g[N]; 24 int find(int x) { 25 return fa[x] == x ? x : fa[x] = find(fa[x]); 26 } 27 void merge(int a, int b) { 28 if ((a = find(a)) != (b = find(b))) fa[b] = a; 29 } 30 void dfs(int u) { 31 while (!g[u].empty()) { 32 int e = *g[u].begin(); 33 if (E[e].u != u) swap(E[e].u, E[e].v); 34 int v = E[e].v; 35 g[u].erase(e); g[v].erase(e); 36 dfs(v); 37 } 38 } 39 int main() { 40 read(n); read(m); 41 for (int i = 1; i <= n; ++i) fa[i] = i; 42 for (int u, v, i = 0; i < m; ++i) { 43 read(u), read(v); 44 E[i] = (Edge){u, v}; 45 g[u].insert(i); 46 g[v].insert(i); 47 ++in[u]; ++in[v]; 48 merge(u, v); 49 } 50 for (int i = 1; i <= n; ++i) 51 if ((in[i] & 1) || find(i) != find(1)) 52 return puts("NO"), 0; 53 dfs(1); puts("YES"); 54 for (int i = 0; i < m; ++i) 55 printf("%d %d\n", E[i].u, E[i].v); 56 return 0; 57 }