TopCoder12808 「SRM594Medium」FoxAndGo3 二分图最大独立集

问题描述

一个 (N imes N) 围棋棋盘,任意两个白子不相邻,你要加入若干个黑子并提出白子,最大化空格数目。

submit


题解

显然最终棋盘的局面不能够一个白子和它周围的空格都是空的,只能属于 「空」 或 「不空」 。

所以是个二分图。

二分图最大独立集=总点数-二分图最大匹配


(mathrm{Code})

#include<bits/stdc++.h>
using namespace std;

//#define file
//#define local

const int INF=0x3f3f3f3f;

int n,S,T;
string s[52];

int Head[2507],Next[500007],to[500007],w[500007],tot=1;

void addedge(int x,int y,int z){
	to[++tot]=y,Next[tot]=Head[x],Head[x]=tot,w[tot]=z;
}
void add(int x,int y,int z){
	addedge(x,y,z);addedge(y,x,0);
}

void Init(void){
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>s[i];
		cout<<s[i]<<endl;
	}
}

bool check(int x,int y){
	return (x>=0&&x<n&&y>=0&&y<n);
}

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

int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};

int d[2507];

bool bfs(void){
	memset(d,0,sizeof(d));
	queue<int>q;q.push(S);d[S]=1;
	while(q.size()){
		int x=q.front();q.pop();
		for(int i=Head[x];i;i=Next[i]){
			int y=to[i];
			if(d[y]||!w[i]) continue;
			d[y]=d[x]+1;q.push(y);
			if(y==T) return true;
		}
	}
	return false;
}

int dfs(int x,int flow){
	if(x==T) return flow;
	int rest=flow;
	for(int i=Head[x];i&&rest;i=Next[i]){
		int y=to[i];
		if(d[y]!=d[x]+1||!w[i]) continue;
		int k=dfs(y,min(rest,w[i]));
		if(!k) d[y]=0;
		else w[i]-=k,w[i^1]+=k,rest-=k;
	}
	return flow-rest;
}

int Dinic(void){
	int t,res(0);
	while(bfs()){
		while(t=dfs(S,INF)) res+=t; 
	}
	return res;
}

void debug(void){
	cout<<n<<endl;
	for(int i=0;i<n;i++) cout<<s[i]<<endl;
	
	for(int i=2;i<=tot;i+=2){
		printf("-- From %d to %d w = %d 
",to[i^1],to[i],w[i]);
	}
	printf("## S = %d , T = %d
",S,T);
}

int reduce;

void Graph_build(void){
	S=n*n+1,T=S+1;
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			if(s[i][j]=='.') add(S,id(i,j),1);
			else if(s[i][j]=='o') add(id(i,j),T,1);
			else ++reduce;
			for(int k=0;k<4;k++){
				int nx=i+dx[k],ny=j+dy[k];
				if(!check(nx,ny)) continue;
				if(s[i][j]=='o'&&s[nx][ny]=='.') add(id(nx,ny),id(i,j),1);
			}
		}
	}
//	debug();
}

int Work(void){
	Graph_build();
	return n*n-reduce-Dinic();
}

#ifndef local
	class FoxAndGo3{
		public:
			int maxEmptyCells(vector<string>vec){
				n=vec[0].size();
				for(int i=0;i<n;i++) s[i]=vec[i];
				return Work();
			}
		};
#endif

#ifdef local
	int main(){
		#ifdef file
			freopen("hzlbn.in","r",stdin);
		#endif
		Init();
		printf("%d
",Work());
		return 0;
	}
#endif
原文地址:https://www.cnblogs.com/liubainian/p/12075183.html