题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3338

题目大意:填数字,使白色区域的值得和等于有值得黑色区域的相对应的值,用网络流来做

题目思路:增加一个源点和汇点,然后左进上出,用源点连左面,容量为相对应的值,汇点连上面,容量是相对应的值,然后左面连空白区域的,容量为8,因为数字为1-9,有下限,但因每个空白必须有值,所以至少为一,所以容量空间为0-8;然后空白区域来连上面,容量同样为8;

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define INF 999999999
#define maxn 14000 #define RE(x) (x)^1
int head[maxn];
int st,ed;//开始节点,结束节点
struct Edge
{
int v,next;
int val;
Edge() {}
Edge( int V , int NEXT , int W = 0 ):v(V),next(NEXT),val(W) {}
} edge[500000];
int lvl[maxn], gap[maxn];
int cnt_edge;
int map[maxn][maxn];
struct gg
{
int x,y;
int val;
} row[maxn],col[maxn];
int emp,row_num,col_num;
int n,m,T;
void Insert_Edge( int u , int v , int flow = 0 )
{ edge[cnt_edge] = Edge(v,head[u],flow);
head[u] = cnt_edge++;
edge[cnt_edge] = Edge(u,head[v]);
head[v] = cnt_edge++; }
void Init()
{
cnt_edge = 0;
memset(head,-1,sizeof(head));
memset(lvl, 0, sizeof (lvl));
memset(gap, 0, sizeof (gap));
}
int dfs(int u, int flow)
{
if (u==ed)
{
return flow;
}
int tf = 0, sf, mlvl = ed-1;
for (int i= head[u]; i != -1; i = edge[i].next)
{
if (edge[i].val > 0)
{
if (lvl[u] ==lvl[edge[i].v]+1)
{
sf = dfs(edge[i].v, min(flow-tf, edge[i].val));
edge[i].val -= sf;
edge[RE(i)].val += sf;
tf += sf;
if (lvl[st] >=ed)
{
return tf;
}
if (tf == flow)
{
break;
}
}
mlvl = min(mlvl, lvl[edge[i].v]);
}
}
if (tf == 0)
{
--gap[lvl[u]];
if (!gap[lvl[u]])
{
lvl[st] =ed;
}
else
{
lvl[u] = mlvl+1;
++gap[lvl[u]];
}
}
return tf;
}
int sap()
{
int ans = 0;
gap[0]=ed;
while (lvl[st] <ed)
{
ans += dfs(st, INF);
}
return ans;
}
int print( int tp )
{
int ans = 0;
int id = tp + row_num+1;
for( int i = head[id] ; i != -1 ; i = edge[i].next )
{
int v = edge[i].v;
if( v <=row_num+1 )
{
ans+= edge[i].val;
break;
}
}
return ans+1;
}
int main()
{
int i,j;
char s[15];
//freopen("F://ACMInput/input.txt","r",stdin);
while(scanf("%d%d",&n,&m)!=-1)
{
emp=row_num=col_num=0;
for(i=0; i<n; i++)
for(j=0; j<m; j++)
{
scanf("%s",s);
if(s[0]=='.')
{
map[i][j]=++emp;
}
else
{
map[i][j]=-1;
if(s[4]!='X')
{
int tp=(s[4]-'0')*100+(s[5]-'0')*10+s[6]-'0';
row[++row_num].x=i;
row[row_num].y=j;
row[row_num].val=tp;
}
if(s[0]!= 'X' )
{
int tp = (s[0]-'0')*100+(s[1]-'0')*10+s[2]-'0';
col[++col_num].x = i;
col[col_num].y = j;
col[col_num].val = tp;
}
}
}
T=emp+col_num+row_num+2;
st=1;
ed=T;
Init();
for(i=1; i<=row_num; i++)
{
int pos = i;
int x = row[i].x;
int y = row[i].y;
int cnt_len = 0;
for( y=y+1; y <m ; y++ )
{
if( map[x][y] != -1 )
{
cnt_len++;
Insert_Edge(i+1, row_num+ map[x][y]+1,8);
}
else break;
}
Insert_Edge(st,pos+1,row[i].val-cnt_len);
} for( i = 1 ; i <=col_num ; i++ )
{
int pos =i+1+row_num+emp;
int x = col[i].x;
int y = col[i].y;
int cnt_len = 0;
for( x=x+1 ; x < n ; x++ )
{
if( map[x][y] != -1 )
{
cnt_len++;
Insert_Edge(row_num+ map[x][y]+1,pos,8); }
else break;
}
Insert_Edge(pos,ed,col[i].val-cnt_len);
}
sap();
for(i=0; i<n; i++)
{
for(j=0; j<m; j++)
{ if(map[i][j]==-1)
printf("_ ");
else
printf("%d ",print(map[i][j]));
}
printf("\n");
}
}
return 0;
}

【最大流】【HDU3338】【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. HDU3338 Kakuro Extension(最大流+思维构图)

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

  4. HDU3338:Kakuro Extension(最大流)

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

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

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

  6. Kakuro Extension【最大流】

    HDU-3338 这道题真的处理起来好复杂啊,题意就是个简单的方格填数问题,但是每个白点至少放1,那么最后的可能解是怎样的呢?我们是不是要把x轴上的和y轴上的统一起来,然后就是每个点都被对应的x和y匹 ...

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

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

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

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

  9. Kakuro Extension HDU - 3338 (Dinic)

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

随机推荐

  1. JSONObject和JSONArray的简单使用(json-lib)

    一. jar包 commons-lang.jar commons-beanutils.jar commons-collections.jar commons-logging.jar ezmorph.j ...

  2. vector的内存分配与释放

    1. vector内存分配 <Effective STL>中"条款14":使用reserve来避免不必要的重新分配 关于STL容器,最神奇的事情之一是只要不超过它们的最 ...

  3. Android漫游记(1)---内存映射镜像(memory maps)

    Android系统内核基于Linux2.6+内核,因此,其在进程内存管理方面的非常多机制和Linux是非常相像的.首先,让我们来看一个典型的Android进程的内存镜像(App进程和Native本地进 ...

  4. Arrays.copyof

    public static int[] copyOf(int[] original, int newLength) { int[] copy = new int[newLength]; System. ...

  5. 出发 Let's Go

    今天是中秋佳节,而恰好我这天过生日,晚上睡觉前又恰好听到温岚唱的祝我生日快乐,心里挺高兴的. 最近,由于公司需要,可能要学习Python和Tribon了,全是未知的,一点不了解的东西,也忽然想起了在这 ...

  6. Mac下Apache服务器配置

    一.Apache服务器 1. 使用最广的 Web 服务器 2. Mac自带,只需要修改几个配置就可以,简单,快捷 3. 有些特殊的服务器功能,Apache都能很好的支持 目的:让有一个自己专属的测试环 ...

  7. 查询DB中每个表占用的空间大小

    使用如下sql script可以获得每个数据库表所占用的空间大小,单位是KB create table #Data(name varchar(100),row varchar(100),reserve ...

  8. 大数值基础、for与while循环的简单对比

  9. struts1:(Struts重构)构建一个简单的基于MVC模式的JavaWeb

    在构建一个简单的基于MVC模式的JavaWeb 中,我们使用了JSP+Servlet+JavaBean构建了一个基于MVC模式的简单登录系统,但在其小结中已经指出,这种模式下的Controller 和 ...

  10. oracle使用还原段的目的和还原数据的管理方法及还原段的类型

    一.引入还原段主要有3个目的: 1.事务回滚:主要是针对rollback语句起作用 2.事务恢复:非正常关闭数据库即非保留事务级关闭数据库(abort.immediate)或者数据库instance崩 ...