Example #1
0
    int getChild(Mate* mate, int level, int take) const {
        assert(1 <= level && level <= n);
        int i = n - level;
        Graph::EdgeInfo const& e = graph.edgeInfo(i);
        assert(e.v1 <= e.v2);

        if (take) {
            switch (takable(mate, e)) {
            case NO:
                return 0;
            case HIT:
                return -1;
            case YES:
                break;
            }

            int w1 = mate[e.v1 - e.v0];
            int w2 = mate[e.v2 - e.v0];
            if (w1 > 0) mate[w1 - e.v0] = w2;
            if (w2 > 0) mate[w2 - e.v0] = w1;
            if (e.v1final || w1 != e.v1) mate[e.v1 - e.v0] = 0;
            if (e.v2final || w2 != e.v2) mate[e.v2 - e.v0] = 0;
        }
        else {
            if (!leavable(mate, e)) return 0;

            Mate& w1 = mate[e.v1 - e.v0];
            Mate& w2 = mate[e.v2 - e.v0];
            if (e.v1final || (e.v1final2 && w1 == e.v1)) w1 = 0;
            if (e.v2final || (e.v2final2 && w2 == e.v2)) w2 = 0;
        }

        if (++i == n) return 0;
        shiftMate(mate, e.v0, graph.edgeInfo(i).v0);

        while (lookahead) {
            Graph::EdgeInfo const& e = graph.edgeInfo(i);
            assert(e.v1 <= e.v2);

            if (takable(mate, e) != NO) break;
            if (!leavable(mate, e)) return 0;
            if (++i == n) return 0;

            Mate& w1 = mate[e.v1 - e.v0];
            Mate& w2 = mate[e.v2 - e.v0];
            if (e.v1final || (e.v1final2 && w1 == e.v1)) w1 = 0;
            if (e.v2final || (e.v2final2 && w2 == e.v2)) w2 = 0;

            shiftMate(mate, e.v0, graph.edgeInfo(i).v0);
        }

        assert(i < n);
        return n - i;
    }
    int getChild(Mate* mate, int level, bool take) const {
        assert(1 <= level && level <= n);
        int i = n - level;
        Graph::EdgeInfo const& e = graph.edgeInfo(i);
        Mate& w1 = mate[e.v1 - e.v0];
        Mate& w2 = mate[e.v2 - e.v0];
        IntSubset const* c1 = constraints[e.v1];
        IntSubset const* c2 = constraints[e.v2];
        assert(e.v1 <= e.v2);
//        std::cerr << "\ne" << i << (take ? ": T " : ": F ")
//                << graph.vertexName(e.v1) << "-" << graph.vertexName(e.v2)
//                << " ";
//        print(std::cerr, mate);

        if (take) {
            if (!takable(c1, w1, e.v1final)) return 0;
            if (!takable(c2, w2, e.v2final)) return 0;
            if (c1) ++w1;
            if (c2) ++w2;
        }
        else {
            if (!leavable(c1, w1, e.v1final)) return 0;
            if (!leavable(c2, w2, e.v2final)) return 0;
        }

        if (e.v1final) w1 = 0;
        if (e.v2final) w2 = 0;

        if (++i == n) return -1;
        shiftMate(mate, graph.edgeInfo(i).v0 - e.v0);

        while (true) {
            Graph::EdgeInfo const& e = graph.edgeInfo(i);
            Mate& w1 = mate[e.v1 - e.v0];
            Mate& w2 = mate[e.v2 - e.v0];
            IntSubset const* c1 = constraints[e.v1];
            IntSubset const* c2 = constraints[e.v2];
            assert(e.v1 <= e.v2);

            if (takable(c1, w1, e.v1final) && takable(c2, w2, e.v2final)) break;
            if (!leavable(c1, w1, e.v1final)) return 0;
            if (!leavable(c2, w2, e.v2final)) return 0;

            if (e.v1final) w1 = 0;
            if (e.v2final) w2 = 0;

            if (++i == n) return -1;
            shiftMate(mate, graph.edgeInfo(i).v0 - e.v0);
        }

        assert(i < n);
        return n - i;
    }