如题,怎么回事呢?
代码如下
#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;
}