此题被誉为神奇最大流,诱惑我去做了下,感觉也是通常的思路。

题意:1.用1-9去填,满足所给的行/列和要求(和那个什么游戏差不多。。。)

求一种合法方案,输出。如:

              

一看,直接就建图了,每个点在白色的点中间,由横和=纵和,管理横和的在左边,纵和的点在右边。S->横和点,纵和点到t,建图即可。

有一点注意,由于只能用1-9去填,是有上下界的网络流问题,所以这里有点比较巧妙,所有白色的点都减去1,和也对应减去几。用0做1,1做2...8做9.一一对应,实现转移为一般最大流问题。最后再加一即可。

  1. #include<iostream>
  2. #include<queue>
  3. #include<cstdio>
  4. #include<cstring>
  5. #include<string>
  6. using namespace std;
  7. const int inf=0x3f3f3f3f;
  8. const int maxv=20100,maxe=1000101;
  9. int nume=0;int head[maxv];int e[maxe][3];
  10. void inline adde(int i,int j,int c)
  11. {
  12. e[nume][0]=j;e[nume][1]=head[i];head[i]=nume;
  13. e[nume++][2]=c;
  14. e[nume][0]=i;e[nume][1]=head[j];head[j]=nume;
  15. e[nume++][2]=0;
  16. }
  17. int ss,tt,n,m;
  18. int vis[maxv];int lev[maxv];
  19. bool bfs()
  20. {
  21. for(int i=0;i<maxv;i++)
  22. vis[i]=lev[i]=0;
  23. queue<int>q;
  24. q.push(ss);
  25. vis[ss]=1;
  26. while(!q.empty())
  27. {
  28. int cur=q.front();
  29. q.pop();
  30. for(int i=head[cur];i!=-1;i=e[i][1])
  31. {
  32. int v=e[i][0];
  33. if(!vis[v]&&e[i][2]>0)
  34. {
  35. lev[v]=lev[cur]+1;
  36. vis[v]=1;
  37. q.push(v);
  38. }
  39. }
  40. }
  41. return vis[tt];
  42. }
  43. int dfs(int u,int minf)
  44. {
  45. if(u==tt||minf==0)return minf;
  46. int sumf=0,f;
  47. for(int i=head[u];i!=-1&&minf;i=e[i][1])
  48. {
  49. int v=e[i][0];
  50. if(lev[v]==lev[u]+1&&e[i][2]>0)
  51. {
  52. f=dfs(v,minf<e[i][2]?minf:e[i][2]);
  53. e[i][2]-=f;e[i^1][2]+=f;
  54. sumf+=f;minf-=f;
  55. }
  56. }
  57. if(!sumf) lev[u]=-1;
  58. return sumf;
  59. }
  60. int dinic()
  61. {
  62. int sum=0;
  63. while(bfs())sum+=dfs(ss,inf);
  64. return sum;
  65. }
  66. struct cell //方块
  67. {
  68. int clour;
  69. int x,y;
  70. };
  71. cell ces[102][102];
  72. void read_build()
  73. {
  74. string ts;
  75. for(int i=0;i<n;i++)
  76. for(int j=0;j<m;j++)
  77. {
  78. cin>>ts;
  79. if(ts=="XXXXXXX") //黑色
  80. {
  81. ces[i][j].clour=0;
  82. ces[i][j].x=ces[i][j].y=-1;
  83. }
  84. else if(ts==".......") //白色
  85. {
  86. ces[i][j].clour=5;
  87. ces[i][j].x=ces[i][j].y=0;
  88. }
  89. else if(ts[0]=='X'&&ts[4]!='X') //横向要填
  90. {
  91. ces[i][j].clour=2;
  92. ces[i][j].x=((ts[4]-'0')*10+(ts[5]-'0'))*10+(ts[6]-'0');
  93. ces[i][j].y=-1;
  94. }
  95. else if(ts[0]!='X'&&ts[4]=='X') //纵向要填
  96. {
  97. ces[i][j].clour=3;
  98. ces[i][j].y=((ts[0]-'0')*10+(ts[1]-'0'))*10+(ts[2]-'0');
  99. ces[i][j].x=-1;
  100. }
  101. else //都要
  102. {
  103. ces[i][j].clour=4;
  104. ces[i][j].y=((ts[0]-'0')*10+(ts[1]-'0'))*10+(ts[2]-'0');
  105. ces[i][j].x=((ts[4]-'0')*10+(ts[5]-'0'))*10+(ts[6]-'0');
  106. }
  107. }
  108. for(int i=0;i<n;i++)
  109. for(int j=0;j<m;j++)
  110. {
  111. //cout<<ces[i][j].clour<<endl;
  112. // cout<<i*m+j<<" ";
  113. }
  114.  
  115. for(int i=0;i<n;i++)
  116. for(int j=0;j<m;j++)
  117. {
  118. int counts=0;
  119. if(ces[i][j].clour==2) //横向的
  120. {
  121. for(int k=j+1;k<m;k++)
  122. {
  123. if(ces[i][k].clour!=5)break;
  124. adde(i*m+j,i*m+k,8);
  125. counts++;
  126. }
  127. adde(ss,i*m+j,ces[i][j].x-counts);
  128. }
  129. else if(ces[i][j].clour==3) //纵向的
  130. {
  131. for(int k=i+1;k<n;k++)
  132. {
  133. if(ces[k][j].clour!=5)break;
  134. adde(k*m+j,i*m+j,8);
  135. counts++;
  136. }
  137. adde(i*m+j,tt,ces[i][j].y-counts);
  138. }
  139. else if(ces[i][j].clour==4) //都要填的,一个格子要2个编号,注意。
  140. {
  141.  
  142. for(int k=j+1;k<m;k++)
  143. {
  144. if(ces[i][k].clour!=5)break;
  145. adde(i*m+j,i*m+k,8);
  146. counts++;
  147. }
  148. adde(ss,i*m+j,ces[i][j].x-counts);
  149. counts=0;
  150. for(int k=i+1;k<n;k++)
  151. {
  152. if(ces[k][j].clour!=5)break;
  153. adde(k*m+j,i*m+j+n*m+2,8);
  154. counts++;
  155. }
  156. adde(i*m+j+n*m+2,tt,ces[i][j].y-counts);
  157. }
  158. }
  159. // adde(0,ss,2);
  160. /* for(int i=0;i<=n*m+1;i++)
  161. for(int j=head[i];j!=-1;j=e[j][1])
  162. {
  163. printf("%d->%d:%d\n",i,e[j][0],e[j][2]);
  164. }*/
  165. }
  166. void out()
  167. {
  168. for(int i=0;i<n;i++)
  169. for(int j=0;j<m;j++)
  170. {
  171. if(ces[i][j].clour!=5)printf("_");
  172. else
  173. {
  174. int sflow=0;
  175. for(int k=head[i*m+j];k!=-1;k=e[k][1]) //统计的时候只要正向边(这里注意!),其实每个点也就一条出的正向边
  176. {
  177. if(k%2==0)
  178. sflow+=8-e[k][2];
  179. }
  180. printf("%d",sflow+1);
  181. }
  182. if(j==m-1)printf("\n");
  183. else printf(" ");
  184. }
  185. }
  186. void init()
  187. {
  188. nume=0;
  189. memset(head,-1,sizeof(head));
  190. ss=n*m;tt=n*m+1;
  191. }
  192. int main()
  193. {
  194. while(~scanf("%d%d",&n,&m))
  195. {
  196. init();
  197. read_build();
  198. dinic();
  199. out();
  200. }
  201. return 0;
  202. }

hdu3338 / 方格横纵和问题终极版,最大流斩的更多相关文章

  1. 08重编终极版《东邪西毒:终极版》DVD粤语中字

    1.东邪西毒].Ashes.of.Time.1994.384p.DVDRip.x264.ac3-DTMM.mkv 这个版本最清晰 ,可惜删减了,只有87分钟,粤语,1.4G. 2.东邪西毒(初始版). ...

  2. 阿里官方Java代码规范标准《阿里巴巴Java开发手册 终极版 v1.3.0》

    终极版 v1.3.0 2017年开春之际,阿里诚意献上重磅大礼:<阿里巴巴Java开发手册>,首次公开阿里官方Java代码规范标准.这套Java统一规范标准将有助于提高行业编码规范化水平, ...

  3. python3 购物车 增改查终极版~

    还是先来条NLP再说,快没了,以后想抄还没有... 十一,没有挫败,只有回应讯息 “挫败”只是指出过去的做法得不到预期的效果,是给我们需要改变的信号. “挫败”只是在事情画上句号时才能用上,欲想事情解 ...

  4. RESTful API终极版序列化封装

    urls: from django.conf.urls import url from app01 import views urlpatterns = [ # url(r"comment/ ...

  5. 通过xshell在linux上安装mysql5.7(终极版)

    通过xshell在linux上安装mysql5.7(终极版) 0)通过xshell连接到远程服务器 1)彻底删除原来安装的mysql 首先查看:rpm -qa|grep -i mysql 删除操作(一 ...

  6. 软件工程课堂作业(五)——终极版随机产生四则运算题目(C++)

    一.升级要求:让程序能接受用户输入答案,并判定对错.最后给出总共对/错的数量. 二.设计思想: 1.首先输入答案并判断对错.我想到的是定义两个数组,一个存放用户算的结果,另一个存放正确答案.每输出一道 ...

  7. 阿里正式发布《Java开发手册》终极版!

    摘要: 本文讲的是阿里正式发布<Java开发手册>终极版!,别人都说我们是码农,但我们知道,自己是个艺术家.也许我们不过多在意自己的外表和穿着,但我们不羁的外表下,骨子里追求着代码的美.质 ...

  8. 终极版Servlet——我只能提示您路过别错过

    终极版Servlet 前言:这两天看了SSM框架,本来是想往后继续学的,脑门一转又回来了,不能就这么不声不响的走了,看了这么多天的Servlet,再写最后一篇做个告别吧,这篇起名为终极版,是我现在所能 ...

  9. 微软不将《帝国时代》终极版上架Steam的原因到底是什么?

    毋庸置疑的是,<帝国时代>绝对是一款经典游戏.作为一款RTS名作,在过去的20年时间中<帝国时代>销量超过2000万部.数以千万计的玩家都沉溺于这款游戏中,<帝国时代&g ...

随机推荐

  1. .Net Core依赖注入中TryAddEnumerable 和TryAddTransient方法的区别

    .Net Core依赖注入添加的每个服务,最终都会转换为一个ServiceDescriptor的实例,ServiceDescriptor包含以下属性: Lifetime:服务的生命周期(Singlet ...

  2. GoF23种设计模式之行为型模式之责任链模式

    一.概述 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并且沿着这条链传递请求,直到有一个对象处理它为止.其设计思想是:给对多个对象处理一个请求的机会, ...

  3. PEP-8 规范1

    代码布局 缩进 每个缩进级别使用4个空格. 延续线应使用Python的隐含线连接在括号,括号和大括号内,或使用悬挂缩进[7],垂直对齐包装元素.使用悬挂式凹痕时,应考虑以下因素;第一行应该没有参数,应 ...

  4. static 的三个作用

    1).用于声明函数体内的变量为静态局部变量,存储在静态数据存储区,在函数被调用过程中维持其值保持不变 2).在文件内(函数体外)被声明为静态的变量,可以被文件内的所有函数访问,但不能被其他文件的函数访 ...

  5. CodeForces 392C Yet Another Number Sequence 矩阵快速幂

    题意: \(F_n\)为斐波那契数列,\(F_1=1,F_2=2\). 给定一个\(k\),定义数列\(A_i=F_i \cdot i^k\). 求\(A_1+A_2+ \cdots + A_n\). ...

  6. UVa 1309 DLX Sudoku

    16×16的数独. 看白书学的DLX,有些细节还有待消化,贴个模板先. #include <cstdio> #include <cstring> #include <al ...

  7. 常用软件URL

    1.MSDN:https://msdn.itellyou.cn/ 2.软碟通(UltraISO)http://rj.baidu.com/soft/detail/11522.html?ald Ultra ...

  8. 鼠标在窗口中的坐标转换到 canvas 中的坐标

        鼠标在窗口中的坐标转换到 canvas 中的坐标 由于需要用到isPointInPath函数,所以必须得将鼠标在窗口中的坐标位置转换到canvas画布中的坐标,今天发现网上这种非常常见的写法其 ...

  9. Leetcode 447.回旋镖的数量

    回旋镖的数量 给定平面上 n 对不同的点,"回旋镖" 是由点表示的元组 (i, j, k) ,其中 i 和 j 之间的距离和 i 和 k 之间的距离相等(需要考虑元组的顺序). 找 ...

  10. Leetcode 433.最小基因变化

    最小基因变化 一条基因序列由一个带有8个字符的字符串表示,其中每个字符都属于 "A", "C", "G", "T"中的任 ...