競プロ記録

問題を解いた際に自分の復習用として使ってます

AGC014 B問題 Unplanned Queries

問題

agc014.contest.atcoder.jp

解説

まずこの問題では木を根付き木として考えます。各辺は偶数回 +1 されていれば良い、つまり各辺の値が0, 2, 4, ...となっていれば良いのでmod2で考えることができます。そして根をrとすると, +1する辺を(a, b)ならば(a,r)と(r,b)に分解できます。それはLAC(aとbのもっとも近い親)をcとするとa-cに+1, b-cに+1, c-r, r-cに+1ずつされることになりr-cは+2で実質操作を行っていないことになります。

次に奇数回しかクエリに出ていない数の中で一番深いノードをxとするとxの上の辺には+1しかされていないため全てを偶数にすることはできません。 よって全ての数に関して出現回数が偶数であればYES, 奇数回の数があればNOとなります。

コード

#include <iostream>
#include <set>
#include <vector>
#include <algorithm>

#define ALL(x) x.begin(), x.end()
using namespace std;

int point[100005];

int main(void){
    int n, m;
    cin >> n >> m;
    for(int i=0; i<m; i++){
        int x, y;
        cin >> x >> y;
        point[x]++;
        point[y]++;
    }
    for(int i=0; i<n; i++){
        if(point[i] % 2 == 1){
            cout << "NO" << endl;
            return 0;
        }
    }
    cout << "YES" << endl;
    return 0;
}