CF1586E. Moment of Bloom ——图论 + 思维* 图中查找两点路径 lca

 CF1586E

题意:

给你一个n个节点m条边的无向图,保证没有重边和自环,给出q个询问,每个询问给出两个点a, b

若存在一种方案使得所有询问后每个点的度都是偶数,则输出yes,并输出每次询问的方案

否则输出no,并输出最少需要再进行多少次询问,使得所有点的入度都是偶数

思路:

显然一个点的度都是偶数当且仅当它在询问中出现了偶数次

所以很容易判断yes or no

所以只要找到每次询问的a到b的任意一条路径就可以了

// Decline is inevitable,
// Romance will last forever.
//#include <bits/stdc++.h>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <deque>
#include <vector>
using namespace std;
#define mst(a, x) memset(a, x, sizeof(a))
#define INF 0x3f3f3f3f
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define fi first
#define se second
#define ll long long
#define int long long
const int maxn = 3e5 + 10;
const int maxm = 1e3 + 10;
const int P = 1e4 + 7;
int n, m, q, lx ,ly, ans;
int x[maxn], y[maxn], px[maxn], py[maxn], deg[maxn];
vector<int> edge[maxn];
int par[maxn], dep[maxn];
bool vis[maxn];
void dfs(int x, int p, int d) {
    par[x] = p;
    dep[x] = d;
    vis[x] = true;
    for(int i = 0; i < (int)edge[x].size(); i++) {
        int y = edge[x][i];
        if(!vis[y])
            dfs(y, x, d+1);
    }
}
void solve() {
    cin >> n >> m;
    for(int i = 1; i <= m; i++) {
        int u, v;
        cin >> u >> v;
        edge[u].pb(v);
        edge[v].pb(u);
    }
    dfs(1, 0, 0);
    cin >> q;
    for(int i = 1; i <= q; i++) {
        cin >> x[i] >> y[i];
        deg[x[i]]++;
        deg[y[i]]++;
    }
    ans = 0;
    for(int i = 1; i <= n; i++)
        ans += (deg[i] & 1);
    if(!ans) {
        cout << "YES\n";
        for(int i = 1; i <= q; i++) {
            int u = x[i];
            int v = y[i];
            lx = ly = 0;
            while(dep[u] > dep[v]) px[++lx] = u, u = par[u];
            while(dep[v] > dep[u]) py[++ly] = v, v = par[v];
            while(u != v) {
                px[++lx] = u, py[++ly] = v;
                u = par[u];
                v = par[v];
            }
            px[++lx] = u;
            cout << lx + ly << endl;
            for(int j = 1; j <= lx; j++)
                cout << px[j] << ' ';
            for(int j =ly ; j >= 1; j--)
                cout << py[j] << ' ';
            cout << endl;
        }
    }
    else cout << "NO\n" << (ans>>1) << endl;
}
signed main() {
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
//    int T; scanf("%d", &T); while(T--)
//    freopen("1.txt","r",stdin);
//    freopen("output.txt","w",stdout);
//    int T; cin >> T;while(T--)
    solve();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_59273843/article/details/120827568