zoukankan      html  css  js  c++  java
  • 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
    
  • 相关阅读:
    Java IO 之 RandomAccessFile 操作文件内容
    Java IO 之 FileFilter与FilenameFilter
    Java IO 之 File 的创建、重命名与遍历
    Java IO 之 System类
    JVM内存区域配置
    切换 显示与隐藏页面元素
    thead tfoot tbody标签的使用
    使用锚点在HTML页面中快速移动
    ASP.NET Core 项目归档
    检测到有潜在危险的 Request.Form 值 转
  • 原文地址:https://www.cnblogs.com/liubainian/p/12075183.html
Copyright © 2011-2022 走看看