[HDU 1565+1569] 方格取数
HDU 1565
方格取数(1)
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5961 Accepted Submission(s): 2268
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
75 15 21
75 15 28
34 70 5
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <set>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
#define N 510 int n;
int src;
int des;
int sum;
int pre[N];
int mpt[N][N];
int map[N][N];
int dir[][]={,,-,,,,,-};
queue<int> q; bool bfs()
{
while(!q.empty()) q.pop();
memset(pre,-,sizeof(pre));
pre[src]=;
q.push(src);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int v=;v<=n*n+;v++)
{
if(pre[v]==- && mpt[u][v]>)
{
pre[v]=u;
if(v==des) return ;
q.push(v);
}
}
}
return ;
}
int EK()
{
int maxflow=;
while(bfs())
{
int minflow=INF;
for(int i=des;i!=src;i=pre[i])
minflow=min(minflow,mpt[pre[i]][i]);
maxflow+=minflow;
for(int i=des;i!=src;i=pre[i])
{
mpt[pre[i]][i]-=minflow;
mpt[i][pre[i]]+=minflow;
}
}
return maxflow;
}
int main()
{
int i,j,k;
while(scanf("%d",&n)!=EOF)
{
sum=;
memset(mpt,,sizeof(mpt));
for(i=;i<=n;i++)
{
for(j=;j<=n;j++)
{
scanf("%d",&map[i][j]);
sum+=map[i][j];
}
}
src=;
des=n*n+;
for(i=;i<=n;i++)
{
for(j=;j<=n;j++)
{
if((i+j)%==) mpt[src][(i-)*n+j]=map[i][j];
else mpt[(i-)*n+j][des]=map[i][j];
}
}
for(i=;i<=n;i++)
{
for(j=;j<=n;j++)
{
if((i+j)%==)
{
for(k=;k<;k++)
{
int x=i+dir[k][];
int y=j+dir[k][];
if(x>= && x<=n && y>= && y<=n)
{
mpt[(i-)*n+j][(x-)*n+y]=INF;
}
}
}
}
}
printf("%d\n",sum-EK());
}
return ;
}
HDU 1569
和方格取数1数据大小不一样,用上面的会超时,可能是写搓了。
邻接表实现 280ms
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <set>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
#define N 20510 struct Edge
{
int to,next,val;
}edge[N];
int tot;
int head[N]; int n;
int m;
int src;
int des;
int sum;
int pre[N];
int path[N];
int map[N][N];
int dir[][]={,,-,,,,,-};
queue<int> q; void init()
{
tot=;
memset(head,-,sizeof(head));
}
void add(int u,int v,int w)
{
edge[tot].to=v;
edge[tot].val=w;
edge[tot].next=head[u];
head[u]=tot++; edge[tot].to=u;
edge[tot].val=;
edge[tot].next=head[v];
head[v]=tot++; }
bool bfs()
{
while(!q.empty()) q.pop();
memset(pre,-,sizeof(pre));
pre[src]=;
q.push(src);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i!=-;i=edge[i].next)
{
int v=edge[i].to;
if(pre[v]==- && edge[i].val>)
{
pre[v]=u;
path[v]=i;
if(v==des) return ;
q.push(v);
}
}
}
return ;
}
int EK()
{
int maxflow=;
while(bfs())
{
int minflow=INF;
for(int i=des;i!=src;i=pre[i])
minflow=min(minflow,edge[path[i]].val);
maxflow+=minflow;
for(int i=des;i!=src;i=pre[i])
{
edge[path[i]].val-=minflow;
edge[path[i]^].val+=minflow;
}
}
return maxflow;
}
int main()
{
int i,j,k;
while(scanf("%d%d",&n,&m)!=EOF)
{
sum=;
init();
for(i=;i<=n;i++)
{
for(j=;j<=m;j++)
{
scanf("%d",&map[i][j]);
sum+=map[i][j];
}
}
src=;
des=n*m+;
for(i=;i<=n;i++)
{
for(j=;j<=m;j++)
{
if((i+j)%==) add(src,(i-)*m+j,map[i][j]);
else add((i-)*m+j,des,map[i][j]);
}
}
for(i=;i<=n;i++)
{
for(j=;j<=m;j++)
{
if((i+j)%==)
{
for(k=;k<;k++)
{
int x=i+dir[k][];
int y=j+dir[k][];
if(x>= && x<=n && y>= && y<=m)
{
add((i-)*m+j,(x-)*m+y,INF);
}
}
}
}
}
printf("%d\n",sum-EK());
}
return ;
}
[HDU 1565+1569] 方格取数的更多相关文章
- HDU 1565 1569 方格取数(最大点权独立集)
HDU 1565 1569 方格取数(最大点权独立集) 题目链接 题意:中文题 思路:最大点权独立集 = 总权值 - 最小割 = 总权值 - 最大流 那么原图周围不能连边,那么就能够分成黑白棋盘.源点 ...
- HDU 1565&1569 方格取数系列(状压DP或者最大流)
方格取数(2) Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU 1565:方格取数(1)(最大点权独立集)***
http://acm.hdu.edu.cn/showproblem.php?pid=1565 题意:中文. 思路:一个棋盘,要使得相邻的点不能同时选,问最大和是多少,这个问题就是最大点权独立集. 可以 ...
- 网络流(最大流) HDU 1565 方格取数(1) HDU 1569 方格取数(2)
HDU 1565 方格取数(1) 给你一个n*n的格子的棋盘,每个格子里面有一个非负数.从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的 ...
- HDU 1569 方格取数(2)
方格取数(2) Time Limit: 5000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 15 ...
- HDU 1569 方格取数(2) (最小割)
方格取数(2) Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- HDU 1569 - 方格取数(2) - [最大点权独立集与最小点权覆盖集]
嗯,这是关于最大点权独立集与最小点权覆盖集的姿势,很简单对吧,然后开始看题. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1569 Time Limi ...
- HDU 1569 方格取数(2)(最大流最小割の最大权独立集)
Description 给你一个m*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大. ...
- hdu - 1565 方格取数(1) && 1569 方格取数(2) (最大点权独立集)
http://acm.hdu.edu.cn/showproblem.php?pid=1565 两道题只是数据范围不同,都是求的最大点权独立集. 我们可以把下标之和为奇数的分成一个集合,把下标之和为偶数 ...
随机推荐
- 09_httpclient测试SOAP协议
[工程截图]注意:无需使用Wsimport生成客户端代码 [HttpClient.java] import java.io.ByteArrayOutputStream; import java.io. ...
- treeview OnSelectedNodeChanged js的方法
可以在OnSelectedNodeChanged的cs中,对node赋值如此: nod.Text = "<span onclick=''>" + node名称 + &q ...
- php 中 isset()函数 和 empty()函数的区别
首先这两个函数都是用来测试变量的状态: isset()函数判断一个变量是否在 如果存在返回true 否则返回false empty()函数判断一个变量是否为空,如果为空返回true 否则返回fals ...
- JS拖拽原理
实现拖拽效果主要跟鼠标的三个事件有关: onmousedown : 选择要拖拽的元素 onmousemove : 移动元素 onmouseup : 释放元素 三个事件的关系: obj.onmoused ...
- 算法之合并排序(mergeSort)
合并排序算法在结构上是递归的,采用分治策略:就是将原有的问题划分为 n 个规模较小但结构与原问题相似的子问题,递归地解决这些子问题,然后合并其结果,就得到原问题的解. 合并排序的模式一般如下: 1.分 ...
- php socket connect permission denied
Linux在php socket连接时报错:permission denied 解决办法: # setsebool httpd_can_network_connect=1 参考来源: http://w ...
- LNMP下防跨站、跨目录安全设置,仅支持PHP 5.3.3以上版本
PHP 5.3.3以上的版本,可以修改/usr/local/php/etc/php.ini在末尾里加入: [HOST=www.vpser.net] open_basedir=/home/wwwroot ...
- iis7以上版本权限控制
IIS7.5中(仅win7,win2008 SP2,win2008 R2支持),应用程序池的运行帐号,除了指定为LocalService,LocalSystem,NetWorkService这三种基本 ...
- 虚拟机添加磁盘LVM分区
参考博客:http://kimjinlsgd.blog.51cto.com/1918030/932210 一.查看磁盘情况 新添加一块磁盘. [root@VMhost /]# fdisk -l Dis ...
- 谈谈GUI的配色和字体选择
对于工控领域的显示屏,显示效果很难和电脑屏幕相比.电脑上操作系统或者各种软件的配色方案,在应用到工业控制屏上就会出现“完全不是所想要”的结果,所以工控领域GUI的色彩.字体的选择还是有特别的讲究. 配 ...