Dinic TLE0 求调
查看原帖
Dinic TLE0 求调
860817
Starstream楼主2023/12/25 09:55
#include <iostream>
#include <cstring>

using namespace std;

const int N = 2010, M = 1000010;
const int INF = 1e9;
int dx[] = {-2, -1, 1, 2, 2, 1, -1, -2};
int dy[] = {1, 2, 2, 1, -1, -2, -2, -1};

int n, S, T, sum;
char g[N][N];
int h[N], e[M], ne[M], f[M], idx;
int d[N], q[N], cur[N];

inline void add(int a, int b, int c)
{
	e[idx] = b, f[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
	e[idx] = a, f[idx] = 0, ne[idx] = h[b], h[b] = idx ++ ;
}

inline int get(int x, int y)
{
	return (x - 1) * n + y;
}

inline bool bfs()
{
	memset(d, -1, sizeof d);
	int hh = 0, tt = 0;
	d[S] = 0, cur[S] = h[S], q[0] = S;

	while (hh <= tt)
	{
		int t = q[hh ++ ];
		for (int i = h[t]; ~i; i = ne[i])
		{
			int j = e[i];
			if (d[j] == -1 && f[i])
			{
				d[j] = d[t] + 1;
				cur[j] = h[j];
				if (j == T) return true;
				q[ ++ tt] = j;
			}
		}
	}
	return false;
}

int find(int u, int lim)
{
	if (u == T) return lim;
	int flow = 0;
	for (int i = cur[u]; ~i && flow < lim; cur[u] = i, i = ne[i])
	{
		int j = e[i];
		if (d[j] == d[u] + 1 && f[i])
		{
			int t = find(j, min(f[i], lim - flow));
			if (!t) d[j] = -1;
			flow += t, f[i] -= t, f[i ^ 1] += t;
		}
	}
	return flow;
}

inline int dinic()
{
	int flow = 0, r = 0;
	while (bfs()) while ((flow = find(S, INF))) r += flow;
	return r;
}

int main()
{
	scanf("%d", &n);
	S = 0, T = n * n + 1;
	for (int i = 1; i <= n; i ++ )
	{
		scanf("%s", g[i] + 1);
		for (int j = 1; j <= n; j ++ )
			if (g[i][j] == '1') sum ++ ;
	}

	for (int i = 1; i <= n; i ++ )
		for (int j = 1; j <= n; j ++ )
			if (g[i][j] == '0')
			{
				if ((i + j) & 1)
				{
					add(S, get(i, j), 1);
					for (int k = 0; k < 8; k ++ )
					{
						int a = i + dx[k], b = j + dy[k];
						if (a < 1 || a > n || b < 1 || b > n || g[a][b] == '1') continue;
						add(get(i, j), get(a, b), INF);
					}
				}
				else add(get(i, j), T, 1);
			}
				
	printf("%d\n", n * n - sum - dinic());
	return 0;
}
2023/12/25 09:55
加载中...