Kakuro Extension

题意:现在有一个n*m的矩形,现在每个白色的点都可以填 [1, 9] 中的一个数字。现在要求每行加起来的值等于左边的那个黑块的右值,每列加起来等于上边那个黑块的左值,求合法方案数。

题解:因为每个点至少是1,如果直接建边跑最大流的话会导致某些点的值为0,现在要保证每个点至少为1,我们可以直接把 s 流向每个白点流量为1, 然后黑点流入白点的流量减少边数的流量,最后跑最大流,输出答案。

代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
  4 #define LL long long
  5 #define ULL unsigned LL
  6 #define fi first
  7 #define se second
  8 #define pb emplace_back
  9 #define lson l,m,rt<<1
 10 #define rson m+1,r,rt<<1|1
 11 #define lch(x) tr[x].son[0]
 12 #define rch(x) tr[x].son[1]
 13 #define max3(a,b,c) max(a,max(b,c))
 14 #define min3(a,b,c) min(a,min(b,c))
 15 typedef pair<int,int> pll;
 16 const int inf = 0x3f3f3f3f;
 17 const LL INF = 0x3f3f3f3f3f3f3f3f;
 18 const LL mod =  (int)1e9+7;
 19 const int N = 100*101 * 2;
 20 const int M = N * 20;
 21 int ans[150][150];
 22 int val[150][150][2];
 23 int head[N], deep[N], cur[N];
 24 int w[M], to[M], nx[M];
 25 int tot;
 26 void add(int u, int v, int val){
 27     w[tot]  = val; to[tot] = v;
 28     nx[tot] = head[u]; head[u] = tot++;
 29
 30     w[tot] = 0; to[tot] = u;
 31     nx[tot] = head[v]; head[v] = tot++;
 32 }
 33 int bfs(int s, int t){
 34     queue<int> q;
 35     memset(deep, 0, sizeof(deep));
 36     q.push(s);
 37     deep[s] = 1;
 38     while(!q.empty()){
 39         int u = q.front();
 40         q.pop();
 41         for(int i = head[u]; ~i; i = nx[i]){
 42             if(w[i] > 0 && deep[to[i]] == 0){
 43                 deep[to[i]] = deep[u] + 1;
 44                 q.push(to[i]);
 45             }
 46         }
 47     }
 48     return deep[t] > 0;
 49 }
 50 int Dfs(int u, int t, int flow){
 51     if(u == t) return flow;
 52     for(int &i = cur[u]; ~i; i = nx[i]){
 53         if(deep[u]+1 == deep[to[i]] && w[i] > 0){
 54             int di = Dfs(to[i], t, min(w[i], flow));
 55             if(di > 0){
 56                 w[i] -= di, w[i^1] += di;
 57                 return di;
 58             }
 59         }
 60     }
 61     return 0;
 62 }
 63
 64 int Dinic(int s, int t){
 65     int ans = 0, tmp;
 66     while(bfs(s, t)){
 67         for(int i = 0; i <= t; i++) cur[i] = head[i];
 68         while(tmp = Dfs(s, t, inf)) ans += tmp;
 69     }
 70     return ans;
 71 }
 72 void init(){
 73     memset(head, -1, sizeof(head));
 74     tot = 0;
 75 }
 76 char str[N];
 77 int n, m;
 78 #define id(i,j) (i-1)*m+j
 79 void GG(){
 80     for(int i = 1; i <= n; i++)
 81         for(int j = 1; j <= m; j++){
 82             if(val[i][j][1] > 0){
 83                 for(int z = head[id(i,j)]; ~z; z = nx[z]){
 84                     if(z&1);
 85                     else {
 86                         int tx = to[z] / m + 1, ty = to[z] % m;
 87                         if(!ty) ty = m, tx -= 1;
 88                         ans[tx][ty] = 9 - w[z] + 1;
 89                     }
 90                 }
 91             }
 92         }
 93 }
 94
 95 int main(){
 96     ///Fopen;
 97     while(~scanf("%d%d", &n, &m)){
 98        init(); for(int i = 1; i <= n; i++)
 99             for(int j = 1; j <= m; j++){
100                 ans[i][j] = 0;
101                 scanf("%s", str+1);
102                 if(str[1] == '.') val[i][j][0] = val[i][j][1] = -2;
103                 else {
104                     if(str[1] == 'X') val[i][j][0] = -1; /// down
105                     else val[i][j][0] = (str[1]-'0')*100 + (str[2]-'0')*10 + str[3] - '0';
106                     if(str[5] == 'X') val[i][j][1] = -1;
107                     else val[i][j][1] = (str[5]-'0')*100 + (str[6]-'0')*10 + str[7] - '0';
108                 }
109             }
110         int s = 0, t = n*m*2+1;
111         for(int i = 1; i <= n; i++){
112             for(int j = 1; j <= m; j++){
113                 if(val[i][j][1] > 0){
114                     int tmp = val[i][j][1];
115                     int z = j+1;
116                     while(z <= m && val[i][z][0] == -2){
117                         add(id(i,j), id(i,z), 9);
118                         add(s, id(i,z), 1);
119                        // cout << i << ' ' << j << "  link   " << i << ' ' << z << endl;
120                         z++;
121                         tmp--;
122                     }
123                     add(s, id(i,j), tmp);
124                     j = z - 1;
125                 }
126             }
127         }
128         for(int j = 1; j <= m; j++)
129             for(int i = 1; i <= n; i++){
130                 if(val[i][j][0] > 0){
131                     int z = i + 1;
132                     add(id(i,j)+n*m, t, val[i][j][0]);
133                     while(z <= n && val[z][j][0] == -2){
134                         add(id(z,j),id(i,j)+n*m,9);
135                         z++;
136                     }
137                     i = z - 1;
138                 }
139         }
140         //puts("Oh mather fuck!!!");
141          int tt = Dinic(s,t);
142          //cout << tt << endl;
143         GG();
144         for(int i = 1; i <= n; i++){
145             for(int j = 1; j <= m; j++){
146                 if(ans[i][j]) printf("%d", ans[i][j]);
147                 else printf("_");
148                 if(j!=m) printf(" ");
149             }
150             puts("");
151         }
152     }
153     return 0;
154 }
155 /*
156 2 2
157 XXXXXXX 009/XXX
158 XXX/009 .......
159 */

View Code

转载于:https://www.cnblogs.com/MingSD/p/9738766.html

HDU 3338 Kakuro Extension相关推荐

  1. HDU - 3338 Kakuro Extension(最大流+思维建边)

    题目链接:点击查看 题目大意:填数游戏,给出一个n*m的矩阵,矩阵中存在三种方块: 纯黑的方块:没什么用 纯白的方块:等待我们填数字的方块 黑色方块上有数字: 左下角有数字:当前黑色方块下面的白色方块 ...

  2. HDU Problem - 3338 Kakuro Extension (最大流,建图)

    题目链接 Problem Description If you solved problem like this, forget it.Because you need to use a comple ...

  3. HDU 3338 网络流 建图

    原题位置http://acm.hdu.edu.cn/showproblem.php?pid=3338 这道题的意思就是 给你一个由黑白方格构成的图 白方格全部空着 黑方格有的会有数字 在左下角的数字表 ...

  4. HDU3338 Kakuro Extension(最大流+思维构图)

    这道题一定要写一下,卡了好久. 题意: 有黑白两种方格,最上边一行和最左边一列一定是黑色,然后其余的地方有可能是黑色,有可能是白色,和白色相邻的黑色方格里有数字(1个或2个), 现在要求在白色方格里填 ...

  5. HDU-3338 Kakuro Extension

    像是一个数独问题,在n*m的矩阵里,有黑格子和白格子 如果黑格子右边为白格子,则会有一个数字sumr,代表右边连续白格子中的数的和 如果黑格子下边为白格子,则会有一个数字sumd,代表下边连续白格子中 ...

  6. 解题报告:【kuangbin带你飞】专题十一 网络流

    目录 A.POJ 3436 ACMComputerFactoryACM\ Computer\ FactoryACM Computer Factory[省选/NOI- ] B.POJ 3281 Dini ...

  7. kuangbin带你飞专题合集

    题目列表 [kuangbin带你飞]专题一 简单搜索 [kuangbin带你飞]专题二 搜索进阶 [kuangbin带你飞]专题三 Dancing Links [kuangbin带你飞]专题四 最短路 ...

  8. 算法学习经典例题整理

    陆续会对本篇博客进行更新! 搜索:https://vjudge.net/contest/292597 区间DP:https://vjudge.net/contest/293892 树状背包:https ...

  9. 杭电OJ分类题目(4)-Graph

    原题出处:HDOJ Problem Index by Type,http://acm.hdu.edu.cn/typeclass.php 杭电OJ分类题目(4) HDU Graph Theory - U ...

最新文章

  1. ATS名词术语(待续)
  2. 闲诗一首:《扬州即行》
  3. 设置串行端口的通信参数
  4. 把现有的typesctipt+react项目接入到electron
  5. IE兼容问题IE6,IE7,IE8,IE9,IE10
  6. 【Android Protobuf 序列化】Protobuf 使用 ( Protobuf 使用文档 | 创建 Protobuf 源文件 | Protobuf 语法 )
  7. AutoHotKey 的使用 —— 使用键盘调节 windows 声音
  8. NS3中数据包添加有效负载
  9. Nodejs 新特性 async await 的使用 以及使用 async await 处理异步
  10. kali linux 模板文件夹,详解kali linux 常用文件与指令路径
  11. pytorch 训练人脸精度不达标
  12. 把Ubuntu安装到移动硬盘
  13. 天空测试显卡软件,自由天空综合驱动包
  14. 计算机应用于针灸,中医针灸临床治疗专家系统的研究与实现
  15. 解决Java应用的后台错误:“操作符不存在: character varying = bytea“
  16. 广东计算机设计大赛作品,2017年广东省大学生计算机设计大赛.doc
  17. 滴滴资深分析专家:数据如何驱动业务增长
  18. install4j的使用
  19. 憨批的语义分割重制版2——语义分割评价指标mIOU的计算
  20. 《设计进化论日本版式设计速查手查手册》菜单版式

热门文章

  1. ARM开发(1) 基于stm32的led跑马灯
  2. 基于蓝桥杯的单片机模块练习——LED跑马灯
  3. 人脸识别太常见?好用才行,利尔达推出一体化人脸识别解决方案
  4. 解决github下载代码总是失败的问题
  5. 数仓建设全流程(附PPT和视频)
  6. 基于Android的运动跑步社交平台app
  7. 新年电子版对联如何制作?手把手教你新奇的对联制作妙招
  8. java awv音频播放界面_java – 使用较新版本的Bouncy Castle时,接收器无法验证SMIME
  9. 单机最快的队列Disruptor解析和使用
  10. 使用maven构建一个基于Java的spark应用程序用于统计唐诗三百首中各汉字出现的次数