考虑把答案进行转化,通过分矩形条,我们能去掉一些夹在#之间的边

那么答案= #个数 - 能去掉的边个数

但去掉是有限制的,同一个#格子的横边和竖边不能同时去掉

把边转化成点,限制变成边。

横竖边的点 和 限制 构成了一个二分图。

问题转化成求这个二分图的最大权独立集!!

上dinic就行了

  1 #include <set>
2 #include <vector>
3 #include <cstdio>
4 #include <cstring>
5 #include <algorithm>
6 #define ull unsigned long long
7 #define ll long long
8 using namespace std;
9 const int N1=200+5, inf=0x3f3f3f3f;
10 int xx[]={-1,1,0,0}, yy[]={0,0,-1,1};
11
12 template <typename _T> void read(_T &ret)
13 {
14 ret=0; _T fh=1; char c=getchar();
15 while(c<'0'||c>'9'){ if(c=='-') fh=-1; c=getchar(); }
16 while(c>='0'&&c<='9'){ ret=ret*10+c-'0'; c=getchar(); }
17 ret=ret*fh;
18 }
19
20 const int N2=8e4+5, M2=N2*8;
21 struct EDGE{
22 int to[M2],nxt[M2],flow[M2],head[N2],cte;
23 void ae(int u,int v,int f)
24 { cte++; to[cte]=v, nxt[cte]=head[u]; flow[cte]=f; head[u]=cte; }
25 void adde(int u,int v,int f)
26 { ae(u,v,f); ae(v,u,0); }
27 }e;
28 int idx(char c){ return c-'0'; }
29
30 int n,m,S,T;
31 int xid[N1][N1],yid[N1][N1],tot;
32 char str[N1][N1];
33
34 int que[N2],hd,tl,cur[N2],dep[N2];
35 int bfs()
36 {
37 int x,j,v;
38 memset(dep,-1,sizeof(dep)); memcpy(cur,e.head,sizeof(cur));
39 hd=1,tl=0; que[++tl]=S; dep[S]=0;
40 while(hd<=tl)
41 {
42 x=que[hd++];
43 for(int j=e.head[x];j;j=e.nxt[j])
44 {
45 v=e.to[j]; if(e.flow[j]<=0||dep[v]!=-1) continue;
46 dep[v]=dep[x]+1; que[++tl]=v;
47 }
48 }
49 return dep[T]!=-1;
50 }
51 int dfs(int x,int limit)
52 {
53 int j,v,flow,ans=0;
54 if(!limit||x==T) return limit;
55 for(j=cur[x];j;j=e.nxt[j])
56 {
57 cur[x]=j; v=e.to[j];
58 if(dep[v]==dep[x]+1 && (flow=dfs(v,min(limit,e.flow[j]))) )
59 {
60 limit-=flow; ans+=flow;
61 e.flow[j]-=flow; e.flow[j^1]+=flow;
62 if(!limit) break;
63 }
64 }
65 return ans;
66 }
67 int Dinic()
68 {
69 int ans=0,flow;
70 while(bfs())
71 {
72 flow=dfs(S,inf);
73 if(!flow) break;
74 ans+=flow;
75 }
76 return ans;
77 }
78
79 int main()
80 {
81 // freopen("a.in","r",stdin);
82 read(n); read(m);
83 for(int i=1;i<=n;i++) scanf("%s",str[i]+1);
84 e.cte=1;
85 for(int i=1;i<n;i++) for(int j=1;j<=m;j++) xid[i][j]=++tot;
86 for(int i=1;i<=n;i++) for(int j=1;j<m;j++) yid[i][j]=++tot;
87 S=++tot; T=++tot;
88 for(int i=1;i<n;i++) for(int j=1;j<=m;j++) e.adde(S,xid[i][j],1);
89 for(int i=1;i<=n;i++) for(int j=1;j<m;j++) e.adde(yid[i][j],T,1);
90 int suma=0,sumb=0;
91 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(str[i][j]=='#')
92 {
93 suma++;
94 int id[4]={-1,-1,-1,-1};
95 for(int k=0;k<4;k++) if(str[i+xx[k]][j+yy[k]]=='#')
96 {
97 if(k==0) id[k]=xid[i-1][j];
98 if(k==1) id[k]=xid[i][j];
99 if(k==2) id[k]=yid[i][j-1];
100 if(k==3) id[k]=yid[i][j];
101 sumb++;
102 }
103 for(int x=0;x<=1;x++) for(int y=2;y<=3;y++) if(id[x]!=-1&&id[y]!=-1)
104 {
105 e.adde(id[x],id[y],1);
106 }
107 }
108 sumb>>=1;
109 sumb-=Dinic();
110 printf("%d\n",suma-sumb);
111 return 0;
112 }

CF1404E Bricks (最大权独立集)的更多相关文章

  1. HDU 1569 方格取数(2)(最大流最小割の最大权独立集)

    Description 给你一个m*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大.   ...

  2. hdu 1569 最大权独立集

    /*最大点权独立集=sum-最小点权覆盖*/ #include<stdio.h> #include<string.h> #include<queue> using ...

  3. BZOJ3275Number——二分图最大权独立集

    题目描述 有N个正整数,需要从中选出一些数,使这些数的和最大.若两个数a,b同时满足以下条件,则a,b不能同时被选1:存在正整数C,使a*a+b*b=c*c2:gcd(a,b)=1 输入 第一行一个正 ...

  4. HDU 1565:方格取数(1)(最大点权独立集)***

    http://acm.hdu.edu.cn/showproblem.php?pid=1565 题意:中文. 思路:一个棋盘,要使得相邻的点不能同时选,问最大和是多少,这个问题就是最大点权独立集. 可以 ...

  5. BZOJ3548 : [ONTAK2010]Party

    首先将朋友通过并查集缩起来,因为$P\geq\frac{n(n-1)}{3}$,所以最后最多剩下$46$个点. 将自相矛盾的点删掉,就变成求最大权独立集问题,这等于求补图的最大团. 然后直接用Bron ...

  6. 最小割 总结&&做题记录

    模型要点: 1.一般适用于二取一问题或者01规划. 2.利用最小割=最大流,转化为最大流求之. 建议阅读胡伯涛的论文 <<最小割模型在信息学竞赛的应用>>,有精彩有序的证明和各 ...

  7. LightOJ1360 Skyscraper(DP)

    题目大概是,一个数轴上n个线段,每个线段都有起始坐标.长度和权值,问从中取出没有公共交点的线段的最大权和. 取k次是个经典的最小费用最大流问题,不过这题建容量网络有20W个点,离散化最多也要6W个点, ...

  8. bzoj 3275 Number(最小割)

    [题意] 给定n个数,要求选出一些数满足 1.存在c,a*a+b*b=c*c 2.gcd(a,b)=1  使得和最大. [思路] 二分图的最大权独立集(可以这么叫么QAQ 先拆点,对于不满足条件的两个 ...

  9. bzoj3275

    容易想到是最小割(最大权独立集)然后每个数拆成两个点,不能同时选的之间连边跑最小割,最后答案=总数-mincut/2 因为这样建图将流量变成了原来的两倍 当然这道题更好的建图方法是分成奇数和偶数两个集 ...

随机推荐

  1. Memory Management in Rust

    程序在运行时需要请求操作系统分配内存以及释放内存,因此,程序员在编写程序时,需要显式(手动)地编写分配和释放内存的代码,或者隐式(自动,由语言保证)地进行内存管理.对于前者,C/C++ 是代表语言,程 ...

  2. 分享一些访问之后显示本机公网ip的url地址

    http://ip.42.pl/raw https://api.ip.sb/ip http://ip.3322.net http://ip.qaros.com http://ip.cip.cc htt ...

  3. Spring Cloud之服务注册中心搭建Eureka Server服务注册中⼼

    Spring Cloud并不与Spring MVC类似是一个开源框架,而是一组解决问题的规范(个人理解).解决哪些问题呢?如下: 1)服务管理:⾃动注册与发现.状态监管 2)服务负载均衡 3)熔断 4 ...

  4. 树莓派安装docker并使用docker图形化工具portainer

    配置环境 系统:Raspbian 11(64位) 设备:树莓派4B 一.安装docker 1.安装 curl -fsSL https://get.docker.com -o get-docker.sh ...

  5. Java中Vo、Po等对象的解释

    PO:全称是 persistant object持久对象 最形象的理解就是一个PO就是数据库中的一条记录. 好处是可以把一条记录作为一个对象处理,可以方便的转为其它对象. BO:全称是 busines ...

  6. C# 提取Word中插入的多媒体文件(视频、音频)

    在Word中可将文件通过OLE对象嵌入的方式插入到文档,包括Word.excel.PDF.PPT.图片.宏文件.文件包等在内的多种文件类型.对文档中已插入的文档对象,也可通过本文中的方法提取出来另存到 ...

  7. [Matlab]求解线性方程组

    转自:http://silencethinking.blog.163.com/blog/static/911490562008928105813169/ AX=B或XA=B在MATLAB中,求解线性方 ...

  8. RDD的运行机制

    1. RDD 的设计与运行原理 Spark 的核心是建立在统一的抽象 RDD 之上,基于 RDD 的转换和行动操作使得 Spark 的各个组件可以无缝进行集成,从而在同一个应用程序中完成大数据计算任务 ...

  9. 由浅入深---MyBatis的全局配置文件

    从我开始接触代码,我就很怕写配置文件,一般的配置文件我都是直接从上一个项目复制到这个项目来改改,可能有部分同学也有我这种痛吧: 我目前一般的做法,先去找找例子(从网上,从github,从官网)之后再改 ...

  10. 通过对比语法差异,让会JAVA的你快速学会Kotlin的开源宝藏项目

    今天有个小伙伴来问TJ君,说自己JAVA用的贼溜,想再学习下Kotlin,问TJ君上手难不难? 怎么说呢?其实TJ君一直觉得语言这方面,是触类旁通.一通百通的,既然JAVA已经贼溜了,想必学其他的语言 ...