98pts求调
  • 板块P4701 粘骨牌
  • 楼主wxk123
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/10/12 22:38
  • 上次更新2024/10/13 10:19:12
查看原帖
98pts求调
235302
wxk123楼主2024/10/12 22:38

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;
	}
}
2024/10/12 22:38
加载中...