Luogu P5030 长脖子鹿放置(网络流)

匈牙利T了,Dinic飞了。。。
按奇偶连

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define R(a,b,c) for(register int a = (b); (a) <= (c); ++(a))
#define nR(a,b,c) for(register int a = (b); (a) >= (c); --(a))
#define Fill(a,b) memset(a, b, sizeof(a))
#define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
#define ll long long
#define u32 unsigned int
#define u64 unsigned long long
 
#define ON_DEBUGG
 
#ifdef ON_DEBUGG
 
#define D_e_Line printf("\n----------\n")
#define D_e(x) cout << (#x) << " : " << x << endl
#define Pause() system("pause")
#define FileOpen() freopen("in.txt", "r", stdin)
#define FileSave() freopen("out.txt", "w", stdout)
#include <ctime>
#define TIME() fprintf(stderr, "\ntime: %.3fms\n", clock() * 1000.0 / CLOCKS_PER_SEC);
  
#else
 
#define D_e_Line ;
#define D_e(x) ;
#define Pause() ;
#define FileOpen() ;
#define FileSave() ;
#define TIME() ;
//char buf[1 << 21], *p1 = buf, *p2 = buf;
//#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
 
#endif
 
using namespace std;
struct ios{
    template<typename ATP>inline ios& operator >> (ATP &x){
        x = 0; int f = 1; char ch;
        for(ch = getchar(); ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
        while(ch >= '0' && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar();
        x *= f;
        return *this;
    }
}io;
 
template<typename ATP>inline ATP Max(ATP a, ATP b){
    return a > b ? a : b;
}
template<typename ATP>inline ATP Min(ATP a, ATP b){
    return a < b ? a : b;
}
template<typename ATP>inline ATP Abs(ATP a){
    return a < 0 ? -a : a;
}

const int N = 207;
const int M = 500007;

int n, m;
int S, T;
struct Edge{
	int nxt, pre, w;
}e[M];
int head[M], cntEdge = 1;
inline void add(int u, int v, int w){
	e[++cntEdge] = (Edge) { head[u], v, w}, head[u] = cntEdge;
}
inline void Add(int u, int v, int w){
	add(u, v, w);
	add(v, u, 0);
}

int cur[M];
int q[M], d[M];
inline bool BFS(){
	int h = 0, t = 1;
	R(i,S,T) d[i] = -1;
	d[S] = 0, q[0] = S;
	while(h != t){
		int u = q[h++];
		if(h > 500000) h = 0; 
		for(register int i = head[u]; i; i = e[i].nxt){
			int v = e[i].pre;
			if(e[i].w && d[v] == -1){
				d[v] = d[u] + 1;
				q[t++] = e[i].pre;
				if(t > 500000) t = 0;
			}
		}
	}
	return d[T] != -1;
}
inline int DFS(int u, int f){
	if(u == T) return f;
	int w, used = 0;
	for(register int i = cur[u]; i; i = e[i].nxt){
		int v = e[i].pre;
		if(d[v] == d[u] + 1){
			w = DFS(v, Min(f - used, e[i].w));
			e[i].w -= w, e[i ^ 1].w += w;
			used += w;
			if(used == f) return f;
		}
	}
	if(!used) d[u] = -1;
	return used;
}
inline int Dinic(){
	int sum = 0;
	while(BFS()){
		R(i,S,T) cur[i] = head[i];
		sum += DFS(S, 0x7fffffff);
	}
	return sum;
}
inline int ID(int x, int y){
	return (x - 1) * m + y;
}

int mark[N][N];
int dx[] = {3, 3, 1, 1, -3, -3, -1, -1}, dy[] = {1, -1, 3, -3, 1, -1, 3, -3};
int main(){
	int K;
	io >> n >> m >> K;
	S = 0, T = n * m + 1;
	R(i,1,K){
		int x, y;
		io >> x >> y;
		mark[x][y] = true;
	}
	R(i,1,n){
		R(j,1,m){
			int id = ID(i, j);
			if(i & 1){
				Add(S, id, 1);
			}
			else{
				Add(id, T, 1);
			}
		}
	}
	R(i,1,n){
		R(j,1,m){
			if(mark[i][j]) continue;
			int id = ID(i, j);
			if(i & 1){
				R(k,0,7){
					int fx = i + dx[k], fy = j + dy[k];
					if(fx < 1 || fx > n || fy < 1 || fy > m || mark[fx][fy]) continue;
					int id2 = ID(fx, fy);
					Add(id, id2, 1);
				}
			}
		}
	}
	
	printf("%d", n * m - K - Dinic());
	return 0;
}
posted @ 2019-09-22 17:30  邱涵的秘密基地  阅读(124)  评论(0编辑  收藏  举报