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

问题描述

一个 \(N \times 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 \n",to[i^1],to[i],w[i]);
    }
    printf("## S = %d , T = %d\n",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\n",Work());
        return 0;
    }
#endif

原文地址:https://www.cnblogs.com/liubainian/p/12075183.html

时间: 2024-11-09 02:52:14

TopCoder12808 「SRM594Medium」FoxAndGo3 二分图最大独立集的相关文章

Topcoder12729 「SRM589Medium」GearsDiv1 二分图最大匹配

问题描述 \(N\) 个齿轮每个齿轮有颜色(RGB),有些齿轮之间会咬合,你需要删除尽量少的齿轮并给每种颜色安排方向使得咬合齿轮不同向.问最多保留多少个齿轮.保证不存在两个相同颜色的齿轮咬合. submit 交互输入输出大毒瘤! 题解 发现对于 RGB 三种颜色的齿轮,相同颜色不会自己和自己咬合. 所以可以枚举哪一种颜色的必须保留,剩下来两种咬合就连边,显然是个二分图. \(\mathrm{Code}\) #include<bits/stdc++.h> using namespace std;

「CodeForces-498C」Array and Operations(数论+网络流)

「CodeForces-498C」Array and Operations给定n个点和m个边集,每次操作可以将相连边的两个点值同时除以一个公约数,问最大操作次数 题意 给定一个长为$n$的数组,以及$m$对下标为$(a,b)$的点对,且满足下标a+b为奇数(即奇数点只与偶数点匹配),每次操作可以将同一组的两个数同时除以一个公约数,问最多能进行多少次操作. 解法 显然题目所给的是一个二分图. 对于每个质因数分开考虑.对于奇数点,向源点连接一个容量为该因子个数的边:对于偶数点,则向汇点建立一个容量为

AC日记——「HNOI2017」单旋 LiBreOJ 2018

#2018. 「HNOI2017」单旋 思路: set+线段树: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 #define maxtree maxn<<2 int val[maxtree],tag[maxtree],L[maxtree],R[maxtree],mid[maxtree]; int op[maxn],ki[maxn],bi[maxn],cnt,size,n,ch[maxn]

「随笔」基于当下的思考

马德,说好的技术blog,变成日记本了... 下午的时候莫名其妙的感到很颓废,因为自己的不够强大感到忧虑和危机感十足.现在每每行走在技术的道路上,常觉得如履薄冰,如芒在背. 上大学之前和现在的心态其实差别挺大的,视野的开阔远远不止局限于自己的脚下.不过,这里的「上大学之前」只是一个时间描述词,并不觉得大学是最适合学习的地方,我很失望. 世界上的人无论性别,区域,宗教,兴趣爱好,总可以在互联网上找到志趣相同的人,总是可以不断打破自己的常识与惯性思维.总是有在相同领域比自己更强的人,挺好的. 关于知

「Unity」与iOS、Android平台的整合:3、导出的Android-Studio工程

本文属于「Unity与iOS.Android平台的整合」系列文章之一,转载请注明出处. Unity默认导出的是Android-Eclipse工程,毕竟Eclipse for Android开发在近一两年才开始没落,用户量还是非常巨大的. 个人认为AndroidStudio非常好用,能轻易解决很多Eclipse解决不了或者很难解决的问题. 所以我将Unity导出的Andoid工程分为Eclipse和AndroidStudio两部分. 不过我之后的相关内容都会使用AndroidStudio,希望依然

大数据和「数据挖掘」是何关系?---来自知乎

知乎用户,互联网 244 人赞同 在我读数据挖掘方向研究生的时候:如果要描述数据量非常大,我们用Massive Data(海量数据)如果要描述数据非常多样,我们用Heterogeneous Data(异构数据)如果要描述数据既多样,又量大,我们用Massive Heterogeneous Data(海量异构数据)--如果要申请基金忽悠一笔钱,我们用Big Data(大数据) 编辑于 2014-02-2817 条评论感谢 收藏没有帮助举报作者保留权利 刘知远,NLPer 4 人赞同 我觉得 大数据

开放的智力8:实用「成功学」

可实现的「成功学」 现在我想为这里的年轻人介绍一种可实现的「成功学」.希望这个我自创的理论,可以改变很多人的一生. 当我们评价一个事情值不值得去做.应该花多少精力去做的时候,应该抛弃单一的视角,而是分两个不同的维度来看,一是该事件将给我带来的收益大小(认知.情感.物质.身体方面的收益皆可计入),即「收益值」:二是该收益随时间衰减的速度,我称为「收益半衰期」,半衰期长的事件,对我们的影响会持续得较久较长. 这两个维度正交以后就形成了一个四象限图.我们生活.学习和工作中的所有事情都可以放进这个图里面

hdu 3829 二分图最大独立集

将孩子看做点,两个孩子间存在矛盾关系则连一条边,最后求二分图最大独立集即可 // // main.cpp // hdu3829 // // Created by Fangpin on 15/5/29. // Copyright (c) 2015年 FangPin. All rights reserved. // #include <iostream> #include <cstdio> #include <cstring> #include <vector>

POJ1466 Girls and Boys【二分图最大独立集】

题目链接: http://poj.org/problem?id=1466 题目大意: 有N个学生,他们之间的某些人比较暧昧,只有认识的人能组成一个集合.问:最多能组成 多少个集合,使得这几个集合之间的学生都没有任何关系. 思路: 从N个图中选出M个点,使得这M个点两两之间没有边,求最大的M是多少.二分图最大独立 集问题.本来应该以男生.女生各一边建二分图求最大独立集,但是这里只有N个点,没有告 诉男生.女生的编号.那么以N个学生为一边.再以N个学生为另一边.将相互联系的人之间 建边.然后求最大匹