Wizard's Tour
Time Limit: 50 Sec Memory Limit: 512 MBDescription
Input
Output
Sample Input
4 5
1 2
3 2
2 4
3 4
4 1
Sample Output
2
4 1 2
4 3 2
HINT
Solution
首先,一个连通块的答案可以是floor(m / 2)。考虑如何构造出一种解。
首先我们先搞出一个dfs树。
那么现在对于一个点,有三种边:1. 非树边;2. 儿子边;3. 父亲边。
我们将非树边和儿子边的优先级看做一样的,父亲边优先级最低。
考虑将边配给点,即这个点是一种走法中的中点。从叶子节点往上做。两两配对这些边。
显然每条边都被尽可能利用了,最后只有与根相连的边可能会有最多一条用不了。
这样就是一种解了。
Code
1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 #include<cstdio> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cmath> 8 #include<vector> 9 using namespace std; 10 typedef long long s64; 11 12 const int ONE = 400005; 13 const int MOD = 1e9 + 7; 14 15 int get() 16 { 17 int res = 1, Q = 1; char c; 18 while( (c = getchar()) < 48 || c > 57) 19 if(c == '-') Q = -1; 20 if(Q) res = c - 48; 21 while( (c = getchar()) >= 48 && c <= 57) 22 res = res * 10 + c - 48; 23 return res * Q; 24 } 25 26 int ans_len; 27 struct power 28 { 29 int l, mid, r; 30 }Ans[ONE * 2]; 31 32 int n, m; 33 int x, y; 34 int next[ONE * 2], first[ONE], go[ONE * 2], tot; 35 int vis[ONE * 2]; 36 37 void Add(int u, int v) 38 { 39 next[++tot] = first[u], first[u] = tot, go[tot] = v; 40 next[++tot] = first[v], first[v] = tot, go[tot] = u; 41 } 42 43 vector <power> A; 44 int fat[ONE]; 45 46 void Dfs(int u) 47 { 48 for(int e = first[u]; e; e = next[e]) 49 { 50 int v = go[e]; 51 if(fat[v] || vis[e]) continue; 52 fat[v] = u, Dfs(v); 53 } 54 55 A.clear(); 56 for(int e = first[u]; e; e = next[e]) 57 if(!vis[e] && fat[u] != go[e]) A.push_back((power){go[e], 0, e}); 58 for(int e = first[u]; e; e = next[e]) 59 if(!vis[e] && fat[u] == go[e]) A.push_back((power){go[e], 0, e}); 60 61 int p = 0, len = A.size(); 62 for(int j = 0; j + 1 < len; j += 2) 63 { 64 vis[A[j].r] = vis[(A[j].r-1^1)+1] = 1; 65 vis[A[j+1].r] = vis[(A[j+1].r-1^1)+1] = 1; 66 Ans[++ans_len] = (power){A[j].l, u, A[j + 1].l}; 67 } 68 } 69 70 int main() 71 { 72 n = get(); m = get(); 73 for(int i = 1; i <= m; i++) 74 x = get(), y = get(), Add(x, y); 75 76 for(int i = 1; i <= n; i++) 77 if(!fat[i]) Dfs(i); 78 79 printf("%d ", ans_len); 80 for(int i = 1; i <= ans_len; i++) 81 printf("%d %d %d ", Ans[i].l, Ans[i].mid, Ans[i].r); 82 }