1 条题解

  • 0
    @ 2025-10-22 17:52:31

    题解

    题目分析

    这是一道算法题目,需要根据具体题目要求进行求解。

    解题思路

    1. 问题分析

    • 仔细阅读题目描述,理解题目要求
    • 分析输入输出格式和约束条件
    • 确定需要使用的算法和数据结构

    2. 算法选择

    • 根据题目特点选择合适的算法
    • 考虑时间复杂度和空间复杂度
    • 确保算法能正确处理所有测试用例

    3. 实现要点

    • 注意边界条件的处理
    • 优化输入输出以提高效率
    • 确保代码的正确性和鲁棒性

    4. 调试和优化

    • 使用测试用例验证算法正确性
    • 分析性能瓶颈并进行优化
    • 确保代码能通过所有测试点

    注意事项

    • 仔细处理数据类型和精度问题
    • 注意数组越界和空指针问题
    • 确保算法的时间复杂度符合要求
    #pragma GCC optimize(2,"Ofast,inline,unroll-loops,no-stack-protector")
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define rep(i,l,r) for(int i=(l),num##i=(r);i<=num##i;++i)
    #define per(i,r,l) for(int i=(r),num##i=(l);i>=num##i;--i)
    #define debug(...) fprintf(stderr,__VA_ARGS__)
    #define fileI(x) freopen(x,"r",stdin)
    #define fileO(x) freopen(x,"w",stdout)
    #define pii pair<int,int>
    #define fi first
    #define se second
    const int N = 2e3 + 5, INF = 0x3f3f3f3f;
    const int dir[4][4] = {
        {0, 1, 2, 3},
        {1, 2, 3, 0},
        {2, 3, 0, 1},
        {3, 0, 1, 2}
    };
    const int dx[4] = {-1, 0, 1, 0};
    const int dy[4] = {0, 1, 0, -1};
    
    int n, m;
    
    const int V = N * 4, M = N * 15;
    struct Flow {
        struct Edge {
            int to, nxt, w, c;
        } e[M << 1];
        int head[V], elen;
        void Insert(int u, int v, int w, int c) {
            e[++elen] = (Edge) {
                v, head[u], w, c
            };
            head[u] = elen;
        }
        void addedge(int u, int v, int w, int c) {
            Insert(u, v, w, c), Insert(v, u, 0, -c);
        }
    
        int n, m, s, t;
    
        int h[V], dis[V];
        int flow[V], pre[V];
        bool vis[V];
        queue<int> que;
    
        Flow() {
            elen = 1;
        }
        void Spfa() {
            rep(i, 0, t) h[i] = INF;
            h[s] = 0, vis[s] = 1;
            que.push(s);
    
            while (!que.empty()) {
                int u = que.front();
                que.pop();
                vis[u] = 0;
    
                for (int i = head[u], v; i; i = e[i].nxt) {
                    v = e[i].to;
    
                    if (e[i].w > 0 && h[v] > h[u] + e[i].c) {
                        h[v] = h[u] + e[i].c;
    
                        if (!vis[v])
                            vis[v] = 1, que.push(v);
                    }
                }
            }
        }
        priority_queue<pii, vector<pii >, greater<pii >> que2;
        bool Dij() {
            rep(i, 0, t) dis[i] = INF, vis[i] = 0;
            dis[s] = 0, flow[s] = INF;
            que2.push({0, s});
    
            while (!que2.empty()) {
                int u = que2.top().se;
                que2.pop();
    
                if (vis[u])
                    continue;
    
                vis[u] = 1;
    
                for (int i = head[u], v, nc; i; i = e[i].nxt) {
                    v = e[i].to;
                    nc = e[i].c + h[u] - h[v];
    
                    if (e[i].w > 0 && dis[v] > dis[u] + nc) {
                        dis[v] = dis[u] + nc;
                        flow[v] = min(flow[u], e[i].w);
                        pre[v] = i;
                        que2.push({dis[v], v});
                    }
                }
            }
    
            return vis[t];
        }
        pii EK() {
            int maxflow = 0, mincost = 0;
    
            while (Dij()) {
                rep(i, 0, t)h[i] += dis[i];
                int v = t, ft = flow[t];
                maxflow += ft;
                mincost += h[t] * ft;
    
                while (v != s) {
                    e[pre[v]].w -= ft;
                    e[pre[v] ^ 1].w += ft;
                    v = e[pre[v] ^ 1].to;
                }
            }
    
            return {maxflow, mincost};
        }
    } F;
    
    // 0 1 2 3: 上右左下
    int ID(int x, int y, int d) {
        return ((x - 1) * m + y - 1) * 4 + d + 1;
    }
    
    #define E(u,v,w,c) F.addedge(u,v,w,c)
    
    int goal;
    
    void Link1(int x, int y, const int d[4]) {
        if (!(x + y & 1)) {
            E(ID(x, y, d[0]), ID(x, y, d[1]), 1, 1);
            E(ID(x, y, d[0]), ID(x, y, d[3]), 1, 1);
            E(ID(x, y, d[0]), ID(x, y, d[2]), 1, 2);
        } else {
            E(ID(x, y, d[1]), ID(x, y, d[0]), 1, 1);
            E(ID(x, y, d[3]), ID(x, y, d[0]), 1, 1);
            E(ID(x, y, d[2]), ID(x, y, d[0]), 1, 2);
        }
    }
    void Link2(int x, int y, const int d[4]) {
        if (!(x + y & 1)) {
            E(ID(x, y, d[0]), ID(x, y, d[2]), 1, 1);
            E(ID(x, y, d[1]), ID(x, y, d[3]), 1, 1);
        } else {
            E(ID(x, y, d[2]), ID(x, y, d[0]), 1, 1);
            E(ID(x, y, d[3]), ID(x, y, d[1]), 1, 1);
        }
    }
    void Link3(int x, int y, const int d[4]) {
        if (!(x + y & 1)) {
            E(ID(x, y, d[1]), ID(x, y, d[0]), 1, 1);
            E(ID(x, y, d[3]), ID(x, y, d[0]), 1, 1);
            E(ID(x, y, d[2]), ID(x, y, d[0]), 1, 2);
        } else {
            E(ID(x, y, d[0]), ID(x, y, d[1]), 1, 1);
            E(ID(x, y, d[0]), ID(x, y, d[3]), 1, 1);
            E(ID(x, y, d[0]), ID(x, y, d[2]), 1, 2);
        }
    }
    int main() {
        ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
        cin >> n >> m;
        int s = F.s = 0, t = F.t = n * m * 4 + 1;
        rep(x, 1, n)rep(y, 1, m) {
            if (x + y & 1) {
                rep(i, 0, 3) {
                    int nx = x + dx[i], ny = y + dy[i];
    
                    if (1 <= nx && nx <= n && 1 <= ny && ny <= m) {
                        E(ID(nx, ny, i ^ 2), ID(x, y, i), 1, 0);
                    }
                }
            }
    
            int S;
            cin >> S;
    
            if (!S)
                continue;
    
            int tot = __builtin_popcount(S);
            goal += tot;
    
            if (!(x + y & 1)) {
    
                rep(i, 0, 3)if (S >> i & 1) {
                    E(s, ID(x, y, i), 1, 0);
                }
            } else {
    
                rep(i, 0, 3)if (S >> i & 1) {
                    E(ID(x, y, i), t, 1, 0);
                }
            }
    
            if (tot == 1) {
                Link1(x, y, dir[__lg(S)]);
            } else if (tot == 2) {
                if (S == 0b1001 || S & S << 1) {
                    Link2(x, y, dir[S == 0b1001 ? 3 : __builtin_ctz(S)]);
                }
            } else if (tot == 3) {
                Link3(x, y, dir[__lg(S ^ 0b1111)]);
            }
        }
        F.Spfa();
        pii ans = F.EK();
    
        if (ans.fi * 2 != goal)
            cout << "-1";
        else
            cout << ans.se;
    
        return 0;
    }
    
    • 1

    信息

    ID
    3766
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者