CCF-201512-4 送货

CCF-201512-4 送货 100分

一年前写的80分,然后后来看来眼,百度的代码全是80的。所以自己补了下。
欧拉回路判断几点:
1.并查集维护图连通性
2.度的判断
3.栈模拟递归

#include <bits/stdc++.h>

using namespace std;
const int MAXN = 1e6 + 10;
const int MAXM = 1e6 + 10;

int n, m, first[MAXN], sign, vis[MAXN];

struct Edge {
    int to, w, next;
} edge[MAXM * 4];

struct Node {
    int u, v;
} arr[MAXM];

bool cmp(const Node &a, const Node &b) {
    return a.u + a.v > b.u + b.v;
}

inline void init() {
    for(int i = 0; i < MAXN; i++ ) {
        first[i] = -1;
        vis[i] = 0;
    }
    sign = 0;
}

inline void add_edge(int u, int v, int w) {
    edge[sign].to = v;
    edge[sign].w = w;
    edge[sign].next = first[u];
    first[u] = sign++;
}

struct DisjointSet {
    int pre[MAXN];
    void init() {
        for(int i = 0; i < MAXN; i++ ) {
            pre[i] = i;
        }
    }
    int findx(int x) {
        return pre[x] == x ? x : pre[x] = findx(pre[x]);
    }
    void join(int x, int y) {
        int fx = findx(x), fy = findx(y);
        if(fx != fy) {
            pre[fx] = fy;
        }
    }
    bool same(int x, int y) {
        return findx(x) == findx(y);
    }
} dset;

int deg[MAXN];

set<pair<int, int> >s;

stack<int>st, ans;

void eulur(int start) {
    while(!st.empty()) {
        st.pop();
    }
    while(!ans.empty()) {
        ans.pop();
    }
    st.push(start);
    while(!st.empty()) {
        int x = st.top(), i = first[x];
        while(~i && vis[i]) {
            i = edge[i].next;
        }
        if(~i) {
            st.push(edge[i].to);
            vis[i] = vis[i ^ 1] = 1;
            vis[i] = 1;
            first[x] = edge[i].next;
        } else {
            st.pop();
            ans.push(x);
        }
    }
}

int main()
{
    scanf("%d %d", &n, &m);
    dset.init();
    init();
    for(int i = 1; i <= m; i++ ) {
        scanf("%d %d", &arr[i].u, &arr[i].v);
    }
    sort(arr + 1, arr + 1 + m, cmp);
    for(int i = 1; i <= m; i++ ) {
        int u, v;
        u = arr[i].u, v = arr[i].v;
        dset.join(u, v);
        deg[u]++;
        deg[v]++;
        add_edge(u, v, 1);
        add_edge(v, u, 1);
    }
    int cnt = 0;
    for(int i = 1; i <= n; i++ ) {
        if(deg[i] & 1) {
            cnt++;
        }
    }
    int num = 0;
    for(int i = 1; i <= n; i++ ) {
        if(dset.pre[i] == i) {
            num++;
        }
    }
    if((cnt == 0 || cnt == 2) && num == 1) {
        eulur(1);
        int first = 1;
        while(!ans.empty()) {
            if(first) {
                first = 0;
            } else {
                printf(" ");
            }
            printf("%d", ans.top());
            ans.pop();
        }
        puts("");
    } else {
        puts("-1");
    }

    return 0;
}

原文地址:https://www.cnblogs.com/Q1143316492/p/9622365.html