HDU-3338

这道题真的处理起来好复杂啊,题意就是个简单的方格填数问题,但是每个白点至少放1,那么最后的可能解是怎样的呢?我们是不是要把x轴上的和y轴上的统一起来,然后就是每个点都被对应的x和y匹配起来,那么,之后,用每个点的x向y建立边,跑最大流,每个点的放的值就是反向边的权值了。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define MP(x, y) make_pair(x, y)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 1e2 + , maxE = 1e5 + , st = ;
pair<int, int> re_xy[];
int N, M, head[], cur[], cnt, ed, id[maxN][maxN], tot, ou[maxN][maxN];
char mp[maxN][maxN][];
int down[maxN][maxN], righ[maxN][maxN];
struct Eddge
{
int nex, to, flow;
Eddge(int a=-, int b=, int c=):nex(a), to(b), flow(c) {}
}edge[maxE];
inline void addEddge(int u, int v, int w)
{
edge[cnt] = Eddge(head[u], v, w);
head[u] = cnt++;
}
inline void _add(int u, int v, int w) { addEddge(u, v, w); addEddge(v, u, ); }
inline void solve(int x, int y)
{
if(mp[x][y][] == 'X' && mp[x][y][] == 'X') { id[x][y] = -; return; }
if(mp[x][y][] == '.') { return; }
re_xy[++tot] = MP(x, y);
id[x][y] = tot;
down[x][y] = righ[x][y] = ;
if(mp[x][y][] != 'X') for(int i=; i<=; i++) down[x][y] = down[x][y] * + mp[x][y][i] - '';
if(mp[x][y][] != 'X') for(int i=; i<=; i++) righ[x][y] = righ[x][y] * + mp[x][y][i] - '';
}
int deep[];
queue<int> Q;
inline bool bfs()
{
for(int i=; i<=ed; i++) deep[i] = ;
deep[st] = ;
while(!Q.empty()) Q.pop();
Q.push(st);
while(!Q.empty())
{
int u = Q.front(); Q.pop();
for(int i=head[u], v, f; ~i; i=edge[i].nex)
{
v = edge[i].to; f = edge[i].flow;
if(f && !deep[v])
{
deep[v] = deep[u] + ;
Q.push(v);
}
}
}
return deep[ed];
}
int dfs(int u, int Dist)
{
if(u == ed) return Dist;
for(int &i=cur[u], v, f; ~i; i=edge[i].nex)
{
v = edge[i].to; f = edge[i].flow;
if(f && deep[v] == deep[u] + )
{
int di = dfs(v, min(Dist, f));
if(di)
{
edge[i].flow -= di;
edge[i^].flow += di;
return di;
}
}
}
return ;
}
inline int Dinic()
{
int ans = , tmp;
while(bfs())
{
for(int i=; i<=ed; i++) cur[i] = head[i];
while((tmp = dfs(st, INF))) ans += tmp;
}
return ans;
}
inline void init()
{
cnt = tot = ;
memset(head, -, sizeof(head));
memset(id, , sizeof(id));
}
int main()
{
while(scanf("%d%d", &N, &M) != EOF)
{
init();
for(int i=; i<=N; i++)
{
for(int j=; j<=M; j++)
{
scanf("%s", mp[i][j] + );
solve(i, j);
}
}
ed = (tot << ) + ;
for(int i=, le_id=, up_id=; i<=N; i++)
{
for(int j=; j<=M; j++)
{
if(mp[i][j][] == '.')
{
for(int dx = i - ; dx > ; dx--)
{
if(id[dx][j])
{
up_id = dx;
down[dx][j]--;
break;
}
}
for(int dy = j - ; dy > ; dy--)
{
if(id[i][dy])
{
le_id = dy;
righ[i][dy]--;
break;
}
}
_add(id[i][le_id], id[up_id][j] + tot, );
}
}
}
for(int i=; i<=N; i++)
{
for(int j=; j<=M; j++)
{
if(id[i][j] > )
{
if(mp[i][j][] != 'X') _add(id[i][j] + tot, ed, down[i][j]);
if(mp[i][j][] != 'X') _add(st, id[i][j], righ[i][j]);
}
}
}
Dinic();
for(int x = ; x <= tot; x++)
{
for(int i=head[x], y, f; ~i; i=edge[i].nex)
{
y = edge[i].to; f = edge[i^].flow;
if(y == st) continue;
ou[re_xy[x].first][re_xy[y - tot].second] = f;
}
}
for(int i=; i<=N; i++)
{
for(int j=; j<=M; j++)
{
if(mp[i][j][] != '.') printf("_");
else printf("%d", ou[i][j] + );
printf("%c", j == M ? '\n' : ' ');
}
}
}
return ;
}
/*
3 3
XXXXXXX 009/XXX XXXXXXX
XXX/009 ....... XXXXXXX
XXXXXXX XXXXXXX XXXXXXX
*/

Kakuro Extension【最大流】的更多相关文章

  1. HDU3338 Kakuro Extension —— 最大流、方格填数类似数独

    题目链接:https://vjudge.net/problem/HDU-3338 Kakuro Extension Time Limit: 2000/1000 MS (Java/Others)     ...

  2. hdu3338 Kakuro Extension 最大流

    If you solved problem like this, forget it.Because you need to use a completely different algorithm ...

  3. HDU - 3338 Kakuro Extension (最大流求解方格填数)

    题意:给一个方格,每行每列都有对白色格子中的数之和的要求.每个格子中的数范围在[1,9]中.现在给出了这些要求,求满足条件的解. 分析:本题读入和建图比较恶心... 用网络流求解.建立源点S和汇点T, ...

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

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

  5. HDU 3338 Kakuro Extension (网络流,最大流)

    HDU 3338 Kakuro Extension (网络流,最大流) Description If you solved problem like this, forget it.Because y ...

  6. HDU3338:Kakuro Extension(最大流)

    Kakuro Extension Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  7. L - Kakuro Extension - HDU 3338 - (最大流)

    题意:有一个填数字的游戏,需要你为白色的块内填一些值,不过不能随意填的,是有一些规则的(废话),在空白的上方和作方给出一些值,如果左下角有值说明下面列的和等于这个值,右上角的值等于这行后面的数的和,如 ...

  8. 【最大流】【HDU3338】【Kakuro Extension】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3338 题目大意:填数字,使白色区域的值得和等于有值得黑色区域的相对应的值,用网络流来做 题目思路:增加 ...

  9. Kakuro Extension HDU - 3338 (Dinic)

    Kakuro puzzle is played on a grid of "black" and "white" cells. Apart from the t ...

随机推荐

  1. VS2015+QT环境配置后,Lauch Qt Designer打开失败,无法打开*.ui文件

    最近在VS2015上配置QT时出现了这个问题,遂百度其解决方法,解决之后记录下来.第一步: 在[解决方案资源管理器]中,右击你的 xxx.ui文件,选择[打开方式],此时列表中默认值是[ Qt des ...

  2. csrf原理及flask的处理方法

    csrf原理及flask的处理方法 为什么需要CSRF? Flask-WTF 表单保护你免受 CSRF 威胁,你不需要有任何担心.尽管如此,如果你有不包含表单的视图,那么它们仍需要保护. 例如,由 A ...

  3. CocosCreator与Laya2.0区别

    1图集: Laya:直接拖拽res里面的图片,当生成图集后,会自动优先使用图集的 Cocos:应该先打图集,且图集里的图就是图集里的图,资源里的图就是资源里的.2者不同 addChild Laya:会 ...

  4. python pickle模块的用法

    pickle用于python特有的类型,和python的数据类型间进行转换,提供四个功能 dumps,dump,loads,load. pickle 的用法 #pickle.dumps 将数据通过特殊 ...

  5. 你浏览器的书签栏还够用么? - 程序员学点xx 特辑

    lluxury 运维开发时间 为什么会想到这个话题,是因为最近看到的一条广告:注册 xx 送2048GB资料.yann 暗自感慨:"都9012年了,还有人分享家里的祖传硬盘".2T ...

  6. C#开发 WinForm如何在选项卡中集成加载多个窗体 实现窗体复用

    http://blog.csdn.net/upi2u/article/details/37914909 最近需要做的一个项目,为了避免从菜单中选择的麻烦,需要把几个窗体集成到一起,通过TabContr ...

  7. 11-jQuery简介和选择器

    # jQuery > jQuery是一个是免费.开源的javascript库, 也是目前使用最广泛的javascript函数库.>> jQuery极大的方便你完成web前段的相关操作 ...

  8. spark复习笔记(3):使用spark实现单词统计

    wordcount是spark入门级的demo,不难但是很有趣.接下来我用命令行.scala.Java和python这三种语言来实现单词统计. 一.使用命令行实现单词的统计 1.首先touch一个a. ...

  9. linux搭建tomcat集群+nginx

    安装JDK 一.官方下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 下 ...

  10. JavaScript、ES6中的类的继承

    类的继承 extends  connstructor  super 例1: class Father { constructor(){} money(){ console.log("1000 ...