据说是网络流棋盘模型了

我们把每一个连续子段都看成一个点,我们先把所有的行上的连续子段找出来给他们编上号,所有列上的连续子段找出来也编上号

现在每个格子都有两个编号了,\(a[i][j]\)表示行所对应的连续子段的编号,\(b[i][j]\)表示列所对应的连续子段的编号

之后我们就需要把这些子段匹配起来就可以了,如果\(map[i][j]=='*'\),我们就从\(a[i][j]\)向\(b[i][j]\)连边,就可以表达出一个行连续子段只能和一个列连续子段匹配了

代码

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #include<queue>
  5. #include<algorithm>
  6. #define maxn 2505
  7. #define re register
  8. #define LL long long
  9. #define inf 999999999
  10. #define max(a,b) ((a)>(b)?(a):(b))
  11. #define min(a,b) ((a)<(b)?(a):(b))
  12. inline int read()
  13. {
  14. char c=getchar();re int x=0;
  15. while(c<'0'||c>'9') c=getchar();
  16. while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
  17. }
  18. struct E{int v,nxt,w,f;} e[maxn*1000];
  19. int n,m,num=1,S,T,cnt,tot=1;
  20. int head[maxn],cur[maxn],d[maxn];
  21. char map[55][55];
  22. int a[55][55],b[55][55];
  23. inline void add_edge(int x,int y,int z){e[++num].v=y;e[num].nxt=head[x];head[x]=num;e[num].w=z;}
  24. inline void C(int x,int y,int z){add_edge(x,y,z),add_edge(y,x,0);}
  25. inline int BFS()
  26. {
  27. std::queue<int> q;
  28. for(re int i=S;i<=tot;i++) cur[i]=head[i],d[i]=0;d[S]=1;d[T]=0;
  29. q.push(S);
  30. while(!q.empty())
  31. {
  32. int k=q.front();q.pop();
  33. for(re int i=head[k];i;i=e[i].nxt)
  34. if(!d[e[i].v]&&e[i].w>e[i].f) d[e[i].v]=d[k]+1,q.push(e[i].v);
  35. }
  36. return d[T];
  37. }
  38. int dfs(int x,int now)
  39. {
  40. if(x==T||!now) return now;
  41. int flow=0,ff;
  42. for(re int& i=cur[x];i;i=e[i].nxt)
  43. if(d[e[i].v]==d[x]+1)
  44. {
  45. ff=dfs(e[i].v,min(now,e[i].w-e[i].f));
  46. if(!ff) continue;
  47. now-=ff,flow+=ff;
  48. e[i].f+=ff,e[i^1].f-=ff;
  49. if(!now) break;
  50. }
  51. return flow;
  52. }
  53. int main()
  54. {
  55. n=read(),m=read();T=n*m;
  56. for(re int i=1;i<=n;i++)
  57. for(re int j=1;j<=m;j++) std::cin>>map[i][j];
  58. for(re int i=1;i<=n;i++)
  59. {
  60. int sz=0;
  61. for(re int j=1;j<=m;j++)
  62. if(map[i][j]=='#') {if(sz) C(S,tot,1),tot++;sz=0;}
  63. else if(map[i][j]=='*') sz++,a[i][j]=tot;
  64. if(!sz) continue;
  65. C(S,tot,1);tot++;
  66. }
  67. for(re int j=1;j<=m;j++)
  68. {
  69. int sz=0;
  70. for(re int i=1;i<=n;i++)
  71. if(map[i][j]=='#') {if(sz) C(tot,T,1),tot++;sz=0;}
  72. else if(map[i][j]=='*') sz++,b[i][j]=tot;
  73. if(!sz) continue;
  74. C(tot,T,1);tot++;
  75. }
  76. for(re int i=1;i<=n;i++)
  77. for(re int j=1;j<=m;j++) if(map[i][j]=='*') C(a[i][j],b[i][j],1);
  78. int ans=0;
  79. while(BFS())
  80. ans+=dfs(S,inf);
  81. printf("%d\n",ans);
  82. return 0;
  83. }

【[HEOI2016/TJOI2016]游戏】的更多相关文章

  1. [ZJOI2007]矩阵游戏【bzoj1059/洛谷1129】/ [HEOI2016/TJOI2016]游戏

    小QQ是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏――矩阵游戏.矩阵游戏在一个N \times NN×N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行两种 ...

  2. [HEOI2016/TJOI2016]游戏 解题报告

    [HEOI2016/TJOI2016]游戏 看起来就是个二分图匹配啊 最大化匹配是在最大化边数,那么一条边就代表选中一个坐标内的点 但是每一行不一定只会有一个匹配 于是把点拆开,按照'#'划分一下就好 ...

  3. [HEOI2016/TJOI2016]游戏

    Description: 在2016年,佳缘姐姐喜欢上了一款游戏,叫做泡泡堂.简单的说,这个游戏就是在一张地图上放上若干个炸弹,看是否能炸到对手,或者躲开对手的炸弹.在玩游戏的过程中,小H想到了这样一 ...

  4. [luogu2825 HEOI2016/TJOI2016] 游戏 (二分图最大匹配)

    传送门 Description 在2016年,佳缘姐姐喜欢上了一款游戏,叫做泡泡堂.简单的说,这个游戏就是在一张地图上放上若干个炸弹,看是否能炸到对手,或者躲开对手的炸弹.在玩游戏的过程中,小H想到了 ...

  5. cdq分治(hdu 5618 Jam's problem again[陌上花开]、CQOI 2011 动态逆序对、hdu 4742 Pinball Game、hdu 4456 Crowd、[HEOI2016/TJOI2016]序列、[NOI2007]货币兑换 )

    hdu 5618 Jam's problem again #include <bits/stdc++.h> #define MAXN 100010 using namespace std; ...

  6. [HEOI2016/TJOI2016]树

    [HEOI2016/TJOI2016]树 思路 做的时候也是糊里糊涂的 就是求最大值的线段树 错误 线段树写错了 #include <bits/stdc++.h> #define FOR( ...

  7. 洛谷 P4091 [HEOI2016/TJOI2016]求和 解题报告

    P4091 [HEOI2016/TJOI2016]求和 题目描述 在2016年,佳媛姐姐刚刚学习了第二类斯特林数,非常开心. 现在他想计算这样一个函数的值: \[ f(n)=\sum_{i=0}^n\ ...

  8. 【LG4091】[HEOI2016/TJOI2016]求和

    [LG4091][HEOI2016/TJOI2016]求和 题面 要你求: \[ \sum_{i=0}^n\sum_{j=0}^iS(i,j)*2^j*j! \] 其中\(S\)表示第二类斯特林数,\ ...

  9. 洛谷 P4093 [HEOI2016/TJOI2016]序列 解题报告

    P4093 [HEOI2016/TJOI2016]序列 题目描述 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能会变化,但同一个时刻最多只有一 ...

随机推荐

  1. Java基础26-对象初始化过程

    /* 1.因为new Test1()用到了Test1类,所以会把它从硬盘上加载进入内存 2.如果有static静态代码块就会随着类的加载而执行,还有静态成员和普通方法也会随着类的加载而被加载 3.在堆 ...

  2. vue懒加载 && 浏览器高度

    当我们进入首页时,可能有很多条目需要显示,但是如果条目太多,我们全部将之显示出来就会造成性能的消耗,比如,我在第一条就找到了需要的或者我就看前面两条我就不想看后面的了,所以,这时候如果使用全部加载的方 ...

  3. webservice 介绍

    Web service 即web服务,它是一种跨编程语言和跨操作系统平台的远程调用技术即跨平台远程调用技术. l 采用标准SOAP(Simple Object Access Protocol)  协议 ...

  4. 如何实现一个简单的MVVM框架

    接触过web开发的同学想必都接触过MVVM,业界著名的MVVM框架就有AngelaJS.今天闲来无事,决定自己实现一个简单的MVVM框架玩一玩.所谓简单,就是仅仅实现一个骨架,仅表其意,不摹其形. 分 ...

  5. vs2013下c++调用python脚本函数 出现的一些问题总结

    原文作者:aircraft 原文地址:https://www.cnblogs.com/DOMLX/p/9530834.html 首先是配置: 使用VS2013创建工程. 将libs中的python27 ...

  6. Column 'orders' in order clause is ambiguous

    今天报了这个错误 原因是.当使用sql查询语句,使用了join查表.但是这个orders没指定是哪张表的字段 ,发生在自关联情况

  7. 清除浮动clear-left-right-both-none效果

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  8. Java入门系列-08-选择结构

    这篇文章为你搞懂2个问题 if-else选择结构的使用? switch 的使用? 前面我们学习的代码都是直上直下的执行,还不会"拐弯",这篇文章带大家来看一下会"拐弯&q ...

  9. 数据类型之Nullable

    Nullable 此结构在 .NET Framework 2.0 版中是新增的.

  10. CSP学习之导出密钥BLOB 解析

    通过CryptExportKey( hKey, NULL, PUBLICKEYBLOB,0, NULL, &dwBlobLen) 函数导出的公钥信息如下: 06 02 00 00 00 A4 ...