您的位置:首页 > 理论基础 > 计算机网络

AC日记——[网络流24题]方格取数问题 cogs 734

2017-03-04 16:12 357 查看

734. [网络流24题] 方格取数问题

★★☆ 输入文件:
grid.in
输出文件:
grid.out
简单对比
时间限制:1 s 内存限制:128 MB

«问题描述:

在一个有m*n 个方格的棋盘中,每个方格中有一个正整数。现要从方格中取数,使任

意2 个数所在方格没有公共边,且取出的数的总和最大。试设计一个满足要求的取数算法。

«编程任务:

对于给定的方格棋盘,按照取数要求编程找出总和最大的数。

«数据输入:

由文件grid.in提供输入数据。文件第1 行有2 个正整数m和n,分别表示棋盘的行数

和列数。接下来的m行,每行有n个正整数,表示棋盘方格中的数。

«结果输出:

程序运行结束时,将取数的最大总和输出到文件grid.out中。

输入文件示例 输出文件示例

grid.in

3 3

1 2 3

3 2 3

2 3 1

grid.out

11

(1<=N,M<=30)

思路:

  取数;

  取出的数满足任意两两坐标不相邻;

  所以,我们把点标记;

  把全部的点都用bfs标记成true或者false;

  true与true不相邻,false与false不相邻;

  然后标记为true的点在集合a;

  标记为false的点在集合b;

  建立超级源点s和超级汇点t;

  s向a的每个点连边,流量为点的权值;

  t向b的每个点连边,流量为点的权值;

  然后,a中与b相邻的点连边,流量无限大;

  然后求出最小割;

  最后的ans等于所有点权值的总和减去最小割;

来,上代码:

#include <queue>
#include <cstdio>
#include <iostream>

using namespace std;

struct ColorNode {
int x,y;
bool color;
};

struct EdgeType {
int v,f,e;
};
struct EdgeType edge[900000];

const int dx[5]={0,-1,0,1,0};
const int dy[5]={0,0,1,0,-1};

int n,m,dis[50][50],ans,head[1001],s=0,t;
int cnt=1,deep[1001];

bool if_[50][50];

char Cget;

inline void in(int &now)
{
now=0,Cget=getchar();
while(Cget>'9'||Cget<'0') Cget=getchar();
while(Cget>='0'&&Cget<='9')
{
now=now*10+Cget-'0';
Cget=getchar();
}
}

struct ColorNode node(int x,int y,int color)
{
struct ColorNode pos;
pos.x=x,pos.y=y,pos.color=color;
return pos;
}

inline void edge_add(int u,int v,int f)
{
edge[++cnt].v=v,edge[cnt].f=f,edge[cnt].e=head[u],head[u]=cnt;
edge[++cnt].v=u,edge[cnt].f=0,edge[cnt].e=head[v],head[v]=cnt;
}

bool BFS()
{
queue<int>que;
for(int i=s;i<=t;i++) deep[i]=-1;
deep[s]=0;que.push(s);
while(!que.empty())
{
int pos=que.front();que.pop();
for(int i=head[pos];i;i=edge[i].e)
{
if(deep[edge[i].v]<0&&edge[i].f>0)
{
deep[edge[i].v]=deep[pos]+1;
if(edge[i].v==t) return true;
que.push(edge[i].v);
}
}
}
return false;
}

int flowing(int now,int flow)
{
if(now==t||flow<=0) return flow;
int oldflow=0;
for(int i=head[now];i;i=edge[i].e)
{
if(edge[i].f<=0||deep[edge[i].v]!=deep[now]+1) continue;
int pos=flowing(edge[i].v,min(edge[i].f,flow));
flow-=pos;
oldflow+=pos;
edge[i].f-=pos;
edge[i^1].f+=pos;
if(flow==0) return oldflow;
}
return oldflow;
}

int main()
{
freopen("grid.in","r",stdin);
freopen("grid.out","w",stdout);
in(n),in(m);t=n*m+1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
in(dis[i][j]);
ans+=dis[i][j];
}
}
queue<ColorNode>que;
if_[1][1]=true;
que.push(node(1,1,if_[1][1]));
while(!que.empty())
{
struct ColorNode pos=que.front();que.pop();
if(pos.color)
{
edge_add(s,(pos.x-1)*m+pos.y,dis[pos.x][pos.y]);
int x=pos.x,y=pos.y,hash=(pos.x-1)*m+pos.y;
for(int i=1;i<=4;i++)
{
if(x+dx[i]>0&&x+dx[i]<=n&&y+dy[i]>0&&y+dy[i]<=m)
{
edge_add(hash,(pos.x+dx[i]-1)*m+pos.y+dy[i],0x7ffffff);
}
}
}
else edge_add((pos.x-1)*m+pos.y,t,dis[pos.x][pos.y]);
if(pos.x+1<=n&&!if_[pos.x+1][pos.y])
{
que.push(node(pos.x+1,pos.y,!pos.color));
if_[pos.x+1][pos.y]=true;
}
if(pos.y+1<=m&&!if_[pos.x][pos.y+1])
{
if_[pos.x][pos.y+1]=true;
que.push(node(pos.x,pos.y+1,!pos.color));
}
}
while(BFS()) ans-=flowing(s,0x7ffffff);
cout<<ans;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: