OIFC未來共同體20241021noip模擬一

bryce_yyds發表於2024-11-01

T1

建邊,發現要找偶環,但兩個奇環也可以拼在一起,於是按照上面的思路模擬即可。

但是掛了一個點,不知道為啥。

#include<iostream>
#include<vector>
#include<cstring>

using namespace std;

inline int read(){register int x = 0, f = 1;register char c = getchar();while (c < '0' || c > '9'){if (c == '-') f = -1;c = getchar();}while (c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return x * f;}

const int N = 1e5 + 10, M = 1e5 + 10;
int T, n, m;
struct edge{
    int v, id, nxt;
}e[M << 1];
int head[N], cnt, in[N];
void add(int u, int v, int id){
    e[++cnt] = (edge){v, id, head[u]};
    head[u] = cnt;
}
bool vis[M], p[N], g[N], h[N], o;
int fir;
vector<int> dfn[N];
struct node{
    int u, DFN, id;
};
vector<node> bian;
int times, tot;
int a[N], b[N];
bool dfs(int u, int id){
    p[u] = 1;
    if (vis[id]) return 0;
    vis[id] = 1;
    times++;
    bian.emplace_back((node){u, times, id});
    dfn[u].emplace_back(times);
    if (dfn[u].size() > 1){
        for (int i = 0; i < dfn[u].size(); i++){
            for (int j = i + 1; j < dfn[u].size(); j++){
                if ((dfn[u][j] - dfn[u][i]) % 2 == 0){
                    while (!bian.empty() && bian.back().DFN > dfn[u][j]) bian.pop_back();
                    int pos = 0, A = 0, B = 0;
                    while (!bian.empty() && bian.back().DFN > dfn[u][i]){
                        if (pos % 2 == 0) a[++A] = bian.back().id, pos++;
                        else b[++B] = bian.back().id, pos++;
                        bian.pop_back();
                    }
                    cout << A << ' ' << B << '\n';
                    for (int k = 1; k <= A; k++) cout << a[k] << ' ';
                    cout << '\n';
                    for (int k = 1; k <= B; k++) cout << b[k] << ' ';
                    cout << '\n';
                    return 1;
                }
            }
        }
        if(tot < 2 && !o){
            if (!g[u]){
                tot++;
                if (tot == 1){
                    for (int k = 0; k < bian.size(); k++)
                        if (bian[k].DFN > dfn[u].front()) g[bian[k].u] = 1;
                }else{
                    for (int k = 0; k < bian.size(); k++)
                        if (bian[k].DFN > dfn[u].front()) h[bian[k].u] = 1, fir = bian[k].u;
                }
            }
        }
    }
    for (int i = head[u]; i; i = e[i].nxt){
        int v = e[i].v;
        if (in[v] <= 1) continue;
        if (dfs(v, e[i].id)) return 1;
    }
    vis[id] = 0;
    times--;
    bian.pop_back();
    if (!dfn[u].empty()) dfn[u].pop_back();
    return 0;
}
int A, B, x, y;
bool tip[N], boom;
int solve1(int u, int id){
    if (tip[u]) return 0;
    if (boom && id) a[++A] = id;
    if (!boom && id) b[++B] = id;
    if (g[u]) return u;
    tip[u] = 1;
    boom ^= 1;
    for (int i = head[u]; i; i = e[i].nxt){
        int v = e[i].v, x = solve1(v, e[i].id);
        if (x){
            if (h[u] && !y) y = u;
            return x;
        }
    }
    boom ^= 1;
    tip[u] = 0;
    if (boom && id) A--;
    if (!boom && id) B--;
    return 0;
}
bool solve2(int x, int u, int fa, int id){
    if (!g[u]) return 0;
    if (tip[u] && x == u){
        if (boom && id) a[++A] = id;
        if (!boom && id) b[++B] = id;
        return 1;
    }
    if (tip[u]) return 0;
    if (boom && id) a[++A] = id;
    if (!boom && id) b[++B] = id;
    tip[u] = 1;
    boom ^= 1;
    for (int i = head[u]; i; i = e[i].nxt){
        int v = e[i].v;
        if (v != fa && solve2(x, v, u, e[i].id)) return 1;
    }
    boom ^= 1;
    tip[u] = 0;
    if (boom && id) A--;
    if (!boom && id) B--;
    return 0;
}
bool solve3(int x, int u, int fa, int id){
    if (!h[u]) return 0;
    if (tip[u] && x == u){
        if (boom && id) a[++A] = id;
        if (!boom && id) b[++B] = id;
        return 1;
    }
    if (tip[u]) return 0;
    if (boom && id) a[++A] = id;
    if (!boom && id) b[++B] = id;
    tip[u] = 1;
    boom ^= 1;
    for (int i = head[u]; i; i = e[i].nxt){
        int v = e[i].v;
        if (v != fa && solve3(x, v, u, e[i].id)) return 1;
    }
    boom ^= 1;
    tip[u] = 0;
    if (boom && id) A--;
    if (!boom && id) B--;
    return 0;
}
void find(int u){
    A = B = boom = 0;
    x = solve1(u, 0);
    solve2(x, x, x, 0);
    boom = 1;
    tip[u] = 0;
    solve3(y, u, y, 0);
    cout << A << ' ' << B << '\n';
    for (int i = 1; i <= A; i++) cout << a[i] << ' ';
    cout << '\n';
    for (int i = 1; i <= B; i++) cout << b[i] << ' ';
    cout << '\n';
}

int main(){
    freopen("bookstore.in", "r", stdin);
    freopen("bookstore.out", "w", stdout);
    T = read();
    while (T--){
        n = read(), m = read();
        for (int i = 1; i <= m; i++){
            int u = read(), v = read();
            add(u, v, i), add(v, u, i);
            in[u]++, in[v]++;
        }
        bool f = 0;
        for (int i = 1; i <= n; i++){
            if (!p[i] && in[i] > 1){
                if (dfs(i, 0)){
                    f = 1;
                    break;
                }else if (tot == 2){
                    o = 1;
                }else{
                    tot = 0;
                    memset(g, 0, sizeof g);
                    memset(h, 0, sizeof h);
                }
            }
        }
        if (!f && tot == 2){
            f = 1;
            find(fir);
            tot = 0;
        }
        if (!f) cout << -1 << '\n';
        times = cnt = tot = fir = o = 0;
        bian.clear();
        for (int i = 1; i <= n; i++) dfn[i].clear();
        memset(head, 0, sizeof head);
        memset(e, 0, sizeof e);
        memset(vis, 0, sizeof vis);
        memset(p, 0, sizeof p);
        memset(in, 0, sizeof in);
        memset(g, 0, sizeof g);
        memset(h, 0, sizeof h);
        memset(tip, 0, sizeof tip);
        memset(vis, 0, sizeof vis);
    }
    return 0;
}

T2

不會。

T3

不會。

T4

不會。

相關文章