求助,LOJ 上满分,洛谷上只有 1 分
  • 板块P4003 无限之环
  • 楼主_maze
  • 当前回复1
  • 已保存回复1
  • 发布时间2023/7/18 16:50
  • 上次更新2023/11/3 09:05:28
查看原帖
求助,LOJ 上满分,洛谷上只有 1 分
149219
_maze楼主2023/7/18 16:50

如题,怎么回事呢?

代码如下

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define F(i, n) for (int i = 1; i <= n; ++i)

const ll N = 2e4 + 5, maxm = 1e6 + 5, INF = 2147483647;

ll n, m;
ll s, t;
namespace wll {
ll st[N], tot = 1, head[N];
struct edge {
    ll to, val, nx, cost;
} e[maxm << 2];
void add(ll u, ll v, ll w, ll c) {
    if (v == -1 || u == -1)
        return ;

    // if (w) cout << u << ' ' << v << ' ' << w << endl;
    e[++ tot].to = v;
    e[tot].val = w;
    e[tot].cost = c;
    e[tot].nx = head[u];
    head[u] = tot;

    if (w)
        add(v, u, 0, -c);
}
ll dis[N], ton[N];
bool bfs() {
    F(i, n) dis[i] = 2147483647;
    dis[s] = 0;
    mempcpy(st, head, sizeof(head));
    queue<ll> q;
    q.push(s);

    while (! q.empty()) {
        ll u = q.front();
        q.pop();
        ton[u] = 0;

        for (ll i = st[u]; i; i = e[i].nx) {
            ll v = e[i].to, w = e[i].val, c = e[i].cost;

            if (w > 0 && dis[v] > dis[u] + c) {
                dis[v] = dis[u] + c;

                if (ton[v] == 0)
                    q.push(v), ton[v] = 1;
            }
        }
    }

    return dis[t] != 2147483647;
}
bool vis[N];
ll dfs(ll u = s, ll flow = INF) {
    if (u == t) {
        return flow;
    }

    vis[u] = 1;
    ll fl = flow;

    for (ll i = st[u]; i; i = e[i].nx) {
        st[u] = i;
        ll v = e[i].to, w = e[i].val, c = e[i].cost;

        if (w > 0 && vis[v] == 0 && dis[v] == dis[u] + c) {
            ll nxflow = dfs(v, min(w, fl));
            fl -= nxflow;
            e[i].val -= nxflow;
            e[i ^ 1].val += nxflow;
        }
    }

    vis[u] = 0;
    return flow - fl;
}
pair<ll, ll> dinic() {
    ll ans = 0, ansc = 0;

    while (bfs())  {
        ll flow = dfs();
        ans += flow, ansc += dis[t] * flow;
    }

    return make_pair(ans, ansc);
}
}
using wll::add;
using wll::dinic;

int cntJie;
int jie[N][5];


signed main() {
    // freopen("text.in", "r", stdin);
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    cin >> n >> m;

    s = ++cntJie;
    t = ++cntJie;

    int x;
    int ans = 0;

    int yin[] = {0, 3, 4, 1, 2};
    int id = 0, u, pd, req = 0;
    auto f = [&](int x, int y) {
        return ((x - 1) * m) + y;
    };
    auto val1 = [&](int u, int p) {
        int val;
        ans += 2;

        if (pd == 1)
            req += 1;

        F(i, 4) {
            val = (i == p) ? -2 : (i == yin[p] ? 0 : -1);
            jie[id][i] = ++cntJie;

            if (pd == 1)
                add(u, jie[id][i], 1, val);
            else
                add(jie[id][i], u, 1, val);
        }

        if (pd == 1)
            add(s, u, 1, 0);
        else
            add(u, t, 1, 0);
    };
    auto val2 = [&](int u, int x1, int x2) {
        if (pd == 1)
            add(s, u, 2, 0);
        else
            add(u, t, 2, 0);

        if (pd == 1)
            req += 2;

        F(i, 4) jie[id][i] = ++cntJie;
        F(i, 4) {
            if (i == x1 || i == x2) {
                if (pd == 1)
                    add(u, jie[id][i], 1, 0);
                else
                    add(jie[id][i], u, 1, 0);
            } else {
                if (pd == 1)
                    add(jie[id][yin[i]], jie[id][i], 1, 1);
                else
                    add(jie[id][i], jie[id][yin[i]], 1, 1);
            }
        }
    };
    auto val3 = [&](int u, int p) {
        int val;
        ans += 4;

        if (pd == 1)
            req += 3;

        F(i, 4) {
            val = (i == p) ? 0 : (i == yin[p] ? -2 : -1);
            jie[id][i] = ++cntJie;

            if (pd == 1)
                add(u, jie[id][i], 1, val);
            else
                add(jie[id][i], u, 1, val);
        }

        if (pd == 1)
            add(s, u, 3, 0);
        else
            add(u, t, 3, 0);
    };
    auto val4 = [&](int u) {
        if (pd == 1)
            req += 4;

        F(i, 4) {
            jie[id][i] = ++cntJie;

            if (pd == 1)
                add(u, jie[id][i], 1, 0);
            else
                add(jie[id][i], u, 1, 0);
        }

        if (pd == 1)
            add(s, u, 4, 0);
        else
            add(u, t, 4, 0);
    };
    auto valline = [&](int u, int p) {
        if (pd == 1)
            req += 2;

        F(i, 4) {
            if (p == i || p + 2 == i) {
                jie[id][i] = ++cntJie;

                if (pd == 1)
                    add(u, jie[id][i], 1, 0);
                else
                    add(jie[id][i], u, 1, 0);
            } else
                jie[id][i] = -1;
        }

        if (pd == 1)
            add(s, u, 2, 0);
        else
            add(u, t, 2, 0);
    };

    F(i, n) {
        F(j, m) {
            cin >> x;
            id = f(i, j), u = ++cntJie;

            if (i & 1)
                pd = j & 1;
            else
                pd = !(j & 1);

            if (x == 1)
                val1(u, 1);

            if (x == 2)
                val1(u, 2);

            if (x == 4)
                val1(u, 3);

            if (x == 8)
                val1(u, 4);

            if (x == 3)
                val2(u, 1, 2);

            if (x == 6)
                val2(u, 2, 3);

            if (x == 12)
                val2(u, 3, 4);

            if (x == 9)
                val2(u, 1, 4);

            if (x == 14)
                val3(u, 1);

            if (x == 13)
                val3(u, 2);

            if (x == 11)
                val3(u, 3);

            if (x == 7)
                val3(u, 4);

            if (x == 15)
                val4(u);

            if (x == 5)
                valline(u, 1);

            if (x == 10)
                valline(u, 2);

            if (x == 0) {
                F(i, 4) jie[id][i] = -1;
            }
        }
    }

    for (int i = 1; i <= n; i ++) {
        for (int j = 1 + (!(i & 1)); j <= m; j += 2) {
            int id = f(i, j);

            if (i > 1)
                add(jie[id][1], jie[id - m][3], 1, 0);

            if (j > 1)
                add(jie[id][4], jie[id - 1][2], 1, 0);

            if (i < n)
                add(jie[id][3], jie[id + m][1], 1, 0);

            if (j < m)
                add(jie[id][2], jie[id + 1][4], 1, 0);
        }
    }

    /*
      F(i, n) {
      F(j, m) {
      F(k, 4) cout << jie[f(i, j)][k] << ' ';
      if (j < m) cout << " | ";
      }
      cout << endl;
      }
    */

    ll flow, cost;
    n = cntJie;
    tie(flow, cost) = dinic();

    if (flow < req)
        cout << -1 << endl;
    else
        cout << ans + cost << endl;



    return ans;
}
2023/7/18 16:50
加载中...