[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 两道题只是数据范围不同,都是求的最大点权独立集. 我们可以把下标之和为奇数的分成一个集合,把下标之和为偶数 ...
随机推荐
- 【转】如何编译安装PHP扩展
本文参考 一开始安装PHP的时候,我们并不知道需要哪些扩展,所以只有等到我们真正用到的时候才想办法去安装. 安装PHP扩展最简单的办法就是 sudo apt-get install php5-xxx ...
- 教了几天C语言 C语言竞赛------家长们你们为什么这么急!!
由于工大某些传统,暑假放一个月,想想有很多事情要做,而且回去也是热着,倒不如不回家了,在哈尔滨正好避暑,又能轻轻松松的吧事情做了,暑假还能有个好的休息,这样想着,最终决定不回去了.其实不回去的话,就会 ...
- find grep
grep grep -rn "hello,world!" * #递归查找当前目录下所有包含hello,world的文件 grep -C number pattern files : ...
- Django数据操作
1.一个模型类代表数据库中的一个表,一个模型类的实例代表这个数据库表中的一条特定的记录. 2.管理器和查询集. 查询集QuerySet表示从数据库中取出来的对象的集合.它可以含有零个.一个或者多个过滤 ...
- Cent OS 常用 命令
1.开机自动联网操作 需要root权限 vim /etc/sysconfig/network-scripts/ifcfg-p4p1(p4p1 为网络链接名称)这个文件, 把ONBOOT="n ...
- CODEVS 3285 转圈游戏
[题目描述] n 个小伙伴(编号从 0 到 n-1)围坐一圈玩游戏.按照顺时针方向给 n 个位置编号,从0 到 n-1.最初,第 0 号小伙伴在第 0 号位置,第 1 号小伙伴在第 1 号位置,……, ...
- css3 Transition动画执行时有可能会出现闪烁的bug
css3 Transition动画执行时有可能会出现闪烁的bug,一般出现在开始的时候. 解决方法: 1.-webkit-backface-visibility: hidden; 2.-webkit- ...
- 关于如何学好游戏3D引擎编程的一些经验[转]
此篇文章献给那些为了游戏编程不怕困难的热血青年,它的神秘要我永远不间断的去挑战自我,超越自我,这样才能攀登到游戏技术的最高峰 ——阿哲VS自己 QQ79134054多希望大家一起交流与沟通 这篇文章是 ...
- Windows下虚拟Linux
andlinux cygwin virtualbox VMware XenServer
- GDB多进程调试(转)
http://www.cnblogs.com/ggjucheng/archive/2011/12/15/2288710.html GDB 是 linux 系统上常用的 c/c++ 调试工具,功能十分强 ...