• 【Codeforces858F】Wizard's Tour [构造]


    Wizard's Tour

    Time Limit: 50 Sec  Memory Limit: 512 MB

    Description

      

    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 }
    View Code
  • 相关阅读:
    JAVA语法之小结
    JAVA之经典Student问题1
    Android之动画1
    Android之屏幕测试
    Android之点击切换图片
    Android之标签选项卡
    Android简单计算器
    Javascript之相册拖动管理
    Javascript之改变盒子颜色
    CSS之照片翻转
  • 原文地址:https://www.cnblogs.com/BearChild/p/7895789.html
Copyright © 2020-2023  润新知