[codechef] TOURISTS

Tourists in Mancunia

欧拉回路

$wiki$中说

连通的无向图G 有欧拉路径的充要条件是:G中奇顶点(连接的边数量为奇数的顶点)的数目等于0或者2。

连通的无向图G 是欧拉环(存在欧拉回路)的充要条件是:G中每个顶点的度都是偶数。

算法的实现:咱删除每条经过的边就行了。

 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 }

 

posted @ 2018-01-04 22:14  p0ny  阅读(132)  评论(0编辑  收藏  举报