rt,用的dinic,最后一个点一直T实在不会了orz
#include <iostream>
#include <string.h>
#include <queue>
using namespace std;
int N, M, S, T;
int n, m;
#define int long long
const int MAXN = 1001500;
struct B
{
int u, v, w, next;
} p[6000005];
int head[MAXN], cur[MAXN], id = 2;
void build(int u, int v, int w)
{
p[id].u = u;
p[id].v = v;
p[id].w = w;
p[id].next = head[u];
head[u] = id;
id++;
}
int deep[MAXN];
bool bfs(int u, int t)
{
queue<int> que;
memset(deep, -1, sizeof(deep));
for (int i = 1; i <= N; i++)
cur[i] = head[i];
deep[u] = 0;
que.push(u);
while (!que.empty())
{
int uu = que.front();
que.pop();
for (int i = head[uu]; i + 1; i = p[i].next)
{
int v = p[i].v;
if (deep[v] == -1 && p[i].w > 0)
{
deep[v] = deep[uu] + 1;
que.push(v);
if (v == t)
return true;
}
}
}
if (deep[t] != -1)
return true;
return false;
}
int dfs(int u, int minn)
{
int left = minn;
if (u == T || minn == 0)
return minn;
int f = 0;
for (int i = cur[u]; i + 1; i = p[i].next)
{
int v = p[i].v;
if (deep[u] + 1 == deep[v] && p[i].w > 0 && (f = dfs(v, min(left, p[i].w))))
{
left -= f;
p[i].w -= f;
p[i ^ 1].w += f;
}
if (!left)
break;
cur[u] = i;
}
return minn - left;
}
int dinic(int u, int v)
{
int ans = 0;
while (bfs(u, v))
{
ans += dfs(u, 0x3f3f3f3f3f3f3f3f);
}
return ans;
}
int cost[MAXN], k;
int pos2id(int x, int y)
{
return (x - 1) * m + y;
}
int sig[1005][1005];
void addEdge(int x, int y, int w)
{
build(x, y, w);
build(y, x, 0);
}
bool vis[1005][1005];
queue<pair<int, int>> q;
void kuo(int i, int j)
{
if (i >= 3)
{
if (( sig[i - 1][j] == sig[i - 2][j]))
{
addEdge(pos2id(i, j), pos2id(i - 2, j), cost[sig[i-1][j]]);
if (!vis[i - 2][j])
{
vis[i - 2][j] = true;
q.push({i - 2, j});
}
}
}
if (j >= 3)
{
if (( sig[i][j - 1] == sig[i][j - 2]))
{
addEdge(pos2id(i, j), pos2id(i, j - 2), cost[sig[i][j-1]]);
if (!vis[i][j - 2])
{
vis[i][j - 2] = true;
q.push({i, j - 2});
}
}
}
if (i <= n - 2)
{
if (( sig[i + 2][j] == sig[i + 1][j]))
{
addEdge(pos2id(i, j), pos2id(i + 2, j), cost[sig[i+1][j]]);
if (!vis[i + 2][j])
{
vis[i + 2][j] = true;
q.push({i + 2, j});
}
}
}
if (j <= m - 2)
{
if (( sig[i][j + 2] == sig[i][j + 1]))
{
addEdge(pos2id(i, j), pos2id(i, j + 2), cost[sig[i][j+1]]);
if (!vis[i][j + 2])
{
vis[i][j + 2] = true;
q.push({i, j + 2});
}
}
}
}
void BFS()
{
while (!q.empty())
{
auto t = q.front();
q.pop();
kuo(t.first, t.second);
}
}
signed main()
{
// freopen("1.in","r",stdin);
memset(head, -1, sizeof(head));
memset(cur, -1, sizeof(cur));
cin >> n >> m >> k;
S = n * m + 1;
T = n * m + 2;
N = n * m + 2;
for (int i = 1; i <= (n * m - 1) / 2; i++)
{
cin >> cost[i];
}
int x, y;
for (int i = 1; i <= k; i++)
{
cin >> x >> y;
build(pos2id(x, y), T, 0x3f3f3f3f3f3f3f3f);
build(T, pos2id(x, y), 0);
}
pair<int, int> st;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cin >> sig[i][j];
if (!sig[i][j])
{
st.first = i;
st.second = j;
build(S, pos2id(i, j), 0x3f3f3f3f3f3f3f3f);
build(pos2id(i, j), S, 0);
}
}
}
q.push(st);
vis[st.first][st.second] = true;
BFS();
int ans = dinic(S, T);
if (ans == 0x3f3f3f3f3f3f3f3f)
{
cout << "GG";
}
else
{
cout << ans;
}
}