为什么 80pts
查看原帖
为什么 80pts
220824
yyz1005楼主2024/1/17 19:58

思路是因为对于行列奇偶性相同的所有格子,以如下的形式构建成二分图

然后对于不同奇偶性的格子分别 Dinic 一次

看到讨论区有提到不能放的格子有重复的,改了这一点之后 60pts->80pts,错的两个点分别是小了 11 和 66

没看出来哪有问题

#include<bits/stdc++.h>
/*
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#pragma GCC optimize("-fdelete-null-pointer-checks,inline-functions-called-once,-funsafe-loop-optimizations,-fexpensive-optimizations,-foptimize-sibling-calls,-ftree-switch-conversion,-finline-small-functions,inline-small-functions,-frerun-cse-after-loop,-fhoist-adjacent-loads,-findirect-inlining,-freorder-functions,no-stack-protector,-fpartial-inlining,-fsched-interblock,-fcse-follow-jumps,-fcse-skip-blocks,-falign-functions,-fstrict-overflow,-fstrict-aliasing,-fschedule-insns2,-ftree-tail-merge,inline-functions,-fschedule-insns,-freorder-blocks,-fwhole-program,-funroll-loops,-fthread-jumps,-fcrossjumping,-fcaller-saves,-fdevirtualize,-falign-labels,-falign-loops,-falign-jumps,unroll-loops,-fsched-spec,-ffast-math,Ofast,inline,-fgcse,-fgcse-lm,-fipa-sra,-ftree-pre,-ftree-vrp,-fpeephole2",3)
*/
using namespace std;
typedef long long ll;
namespace IO{
	char buf[1 << 20], *p1 = buf, *p2 = buf;
	#define getchar() (p1 == p2 && (p2 = (p1 = buf) + \
		fread(buf, 1, 1 << 20, stdin), p1 == p2) ? EOF : *p1++)
	inline ll read(){
		ll x = 0,h = 1;
		char ch = getchar();
		while(!(ch=='-'||('0'<=ch&&ch<='9'))) ch = getchar();
		if(ch=='-') h = -1;
		else x = ch-'0';
		ch = getchar();
		while('0'<=ch&&ch<='9'){
			x = x*10+ch-'0';
			ch = getchar();
		}
		return x*h;
	}
	inline ll digread(){
		char ch = getchar();
		while(!('0'<=ch&&ch<='9')) ch = getchar();
		return ch-'0';
	}
	inline char readCH(){
		char ch = getchar();
		while(!(ch=='x')) ch = getchar();
		return ch;
	}
	inline void print(ll x){
		if(x>9) print(x/10);
		putchar(x%10+'0');
	}
	inline void write(ll x){
		if(x<0) putchar('-'),x = -x;
		print(x);
	}
}
using namespace IO;
#define File(name)                     \
    freopen(#name ".in", "r", stdin);  \
    freopen(#name ".out", "w", stdout);
#define ERR assert(0)
#define RunTime ((double)clock()/CLOCKS_PER_SEC)
/*
有时候程序没反应就把 IO 里面重定义 getchar 删掉 
-std=c++11  -Wall -Wextra -Wl,--stack=102400000000 -fno-ms-extensions
找不出来哪错了要检查 RE 问题,比如数组开小了,越界,函数返回值
用 long long TLE 可以尝试换成 int
对 vector 进行修改时,要 for(auto &v : vec) v++。必须加 &
n 行 m 列的矩阵先从左到右在从上到下编号,第 i 行 j 列是 (i-1)*m+j
网络流建图正边反边一定连着建
*/
const ll N = 3000010;
const ll INF = 1e16;
struct Edge{
    ll from,to,val,nxt;
} edge[N];
ll D = 0;
ll s,t;
ll head[N],cnt = 1;
ll dis[N],cur[N];
ll dfs(ll id,ll flw){
    if(id==t) return flw;
    ll ret = 0;
    for(ll i = cur[id]; i&&flw>0; i = edge[i].nxt){
        cur[id] = i;
        ll v = edge[i].to;
        if(edge[i].val>0&&dis[v]==dis[id]+1){
            ll diff = dfs(v,min(flw,edge[i].val));
            if(diff==0) dis[v] = INF;
            edge[i].val-=diff;
            edge[i^1].val+=diff;
            ret+=diff;
            flw-=diff;
        }
    }
    return ret;
}
bool bfs(ll id){
    for(ll i = 1; i <= D; i++) dis[i] = INF;
    queue<ll> q;
    q.push(id);
    dis[id] = 0;
    cur[id] = head[id];
    while(!q.empty()){
        ll fir = q.front();
        q.pop();
        for(ll i = head[fir]; i; i = edge[i].nxt){
            ll v = edge[i].to;
            if(edge[i].val>0&&dis[v]==INF){
                q.push(v);
                cur[v] = head[v];
                dis[v] = dis[fir]+1;
                if(v==t) return 1;
            }
        }
    }
    return 0;
}
ll Dinic(){
    ll ans = 0;
    while(bfs(s)) ans+=dfs(s,INF);
    return ans;
}
void AddEdge(ll u,ll v,ll w){
    cnt++;
    edge[cnt].from = u,edge[cnt].to = v,edge[cnt].val = w;
    edge[cnt].nxt = head[u],head[u] = cnt;
}
void add(ll u,ll v,ll w){
	AddEdge(u,v,w);
	AddEdge(v,u,0);
}
void init(){
	cnt = 1;
	memset(head,0,sizeof(head));
	memset(cur,0,sizeof(cur));
}
const ll M = 5010;
ll n,m,Q,res = 0,ex = 0;
bool board[M][M];
#define dot(i,j) (m*(i-1)+j)
#define S (n*m) 
ll nxt[8][2] = {{3,1},{1,3},{3,-1},{-1,3},{-1,-3},{-3,-1},{1,-3},{-3,1}};
#define In_map(i,j) (1<=i&&i<=n&&1<=j&&j<=m&&!board[i][j])
void solve1(){
	init();
	D = S;
	s = ++D,t = ++D;
	for(ll i = 1; i <= n; i++) for(ll j = 1; j <= n; j++) if(In_map(i,j)) if((i+j)&1){
		if(i&1) add(s,dot(i,j),1);
		else add(dot(i,j),t,1);
	}
	for(ll i = 1; i <= n; i++) for(ll j = 1; j <= n; j++) if(In_map(i,j)) if((i+j)&1) for(ll p = 0; p < 8; p++){
		ll dx = i+nxt[p][0],dy = j+nxt[p][1];
		if(In_map(dx,dy)) add(dot(i,j),dot(dx,dy),INF);
	}
	res+=Dinic();
}
void solve2(){
	init();
	D = S;
	s = ++D,t = ++D;
	for(ll i = 1; i <= n; i++) for(ll j = 1; j <= n; j++) if(In_map(i,j)) if(!((i+j)&1)){
		if(i&1) add(s,dot(i,j),1);
		else add(dot(i,j),t,1);
	}
	for(ll i = 1; i <= n; i++) for(ll j = 1; j <= n; j++) if(In_map(i,j)) if(!((i+j)&1)) for(ll p = 0; p < 8; p++){
		ll dx = i+nxt[p][0],dy = j+nxt[p][1];
		if(In_map(dx,dy)) add(dot(i,j),dot(dx,dy),INF);
	}
	res+=Dinic();
}
int main(){
	n = read(),m = read(),Q = read();
	for(ll i = 1; i <= Q; i++){
		ll x = read(),y = read();
		if(board[x][y]) ex++;
		board[x][y] = 1;
	}
	solve1();
	solve2();
	//solve_merge();
	else printf("%lld\n",S-Q+ex-res); 
	fprintf(stderr, "TIME:%.3lf s\n", RunTime);
	return 0;
}
/*

*/

2024/1/17 19:58
加载中...