HDU 1565 方格取数(1)(最大点权独立集)
http://acm.hdu.edu.cn/showproblem.php?pid=1565
题意:
给你一个n*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
思路:
最大点权独立集=点权之和-最小点权覆盖集=最小割=最大流
先来看最小点权覆盖集,也就是选取点覆盖所有的边,并且权值要最小。
解决方法是:
从源点向X集连边,容量为点的权值,Y集向汇点连边,容量也为点的权值。如果u和v这两个点相连的话,则将这两个点连一条有向边,容量为INF,因为我们要割的不是这个。这样,从s到t的路径中,就包含了所有的边,最小点覆盖也就是连通所有边,最小割就是让所有边都不连通,于是求个最大流即可。
这样一来,最大点权独立集也就可以求出来了。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
typedef long long LL; const int maxn=+;
const int INF=0x3f3f3f3f; struct Edge
{
int from,to,cap,flow;
Edge(int u,int v,int w,int f):from(u),to(v),cap(w),flow(f){}
}; struct Dinic
{
int n,m,s,t;
vector<Edge> edges;
vector<int> G[maxn];
bool vis[maxn];
int cur[maxn];
int d[maxn]; void init(int n)
{
this->n=n;
for(int i=;i<n;++i) G[i].clear();
edges.clear();
} void AddEdge(int from,int to,int cap)
{
edges.push_back( Edge(from,to,cap,) );
edges.push_back( Edge(to,from,,) );
m=edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
} bool BFS()
{
queue<int> Q;
memset(vis,,sizeof(vis));
vis[s]=true;
d[s]=;
Q.push(s);
while(!Q.empty())
{
int x=Q.front(); Q.pop();
for(int i=;i<G[x].size();++i)
{
Edge& e=edges[G[x][i]];
if(!vis[e.to] && e.cap>e.flow)
{
vis[e.to]=true;
d[e.to]=d[x]+;
Q.push(e.to);
}
}
}
return vis[t];
} int DFS(int x,int a)
{
if(x==t || a==) return a;
int flow=, f;
for(int &i=cur[x];i<G[x].size();++i)
{
Edge &e=edges[G[x][i]];
if(d[e.to]==d[x]+ && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>)
{
e.flow +=f;
edges[G[x][i]^].flow -=f;
flow +=f;
a -=f;
if(a==) break;
}
}
return flow;
} int Maxflow(int s,int t)
{
this->s=s; this->t=t;
int flow=;
while(BFS())
{
memset(cur,,sizeof(cur));
flow +=DFS(s,INF);
}
return flow;
}
}DC; int n;
int map[][];
int dx[]={,,,-};
int dy[]={,-,,}; int main()
{
while(~scanf("%d",&n))
{
int sum=;
int src=,dst=n*n+;
DC.init(dst+);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
scanf("%d",&map[i][j]);
sum+=map[i][j];
}
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
int id=(i-)*n+j;
int t=(i+j)%;
if(t)
{
DC.AddEdge(src,id,map[i][j]);
for(int k=;k<;k++)
{
int x=dx[k]+i;
int y=dy[k]+j;
if(x<||x>n||y<||y>n) continue;
DC.AddEdge(id,(x-)*n+y,INF);
}
}
else DC.AddEdge(id,dst,map[i][j]);
}
int ans=DC.Maxflow(src,dst);
printf("%d\n",sum-ans);
}
return ;
}
HDU 1565 方格取数(1)(最大点权独立集)的更多相关文章
- HDU 1569 - 方格取数(2) - [最大点权独立集与最小点权覆盖集]
嗯,这是关于最大点权独立集与最小点权覆盖集的姿势,很简单对吧,然后开始看题. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1569 Time Limi ...
- HDU 1565 1569 方格取数(最大点权独立集)
HDU 1565 1569 方格取数(最大点权独立集) 题目链接 题意:中文题 思路:最大点权独立集 = 总权值 - 最小割 = 总权值 - 最大流 那么原图周围不能连边,那么就能够分成黑白棋盘.源点 ...
- hdu - 1565 方格取数(1) && 1569 方格取数(2) (最大点权独立集)
http://acm.hdu.edu.cn/showproblem.php?pid=1565 两道题只是数据范围不同,都是求的最大点权独立集. 我们可以把下标之和为奇数的分成一个集合,把下标之和为偶数 ...
- hdu1569 方格取数(2) 最大点权独立集=总权和-最小点权覆盖集 (最小点权覆盖集=最小割=最大流)
/** 转自:http://blog.csdn.net/u011498819/article/details/20772147 题目:hdu1569 方格取数(2) 链接:https://vjudge ...
- TZOJ 3665 方格取数(2)(最大点权独立集)
描述 给你一个m*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大. 输入 包括多个测试实例 ...
- hdu1569 方格取数 求最大点权独立集
题意:一个方格n*m,取出一些点,要求两两不相邻,求最大和.思路:建图,相邻的点有一条边,则建立了一个二分图,求最大点权独立集(所取点两两无公共边,权值和最大),问题转化为求总权和-最小点权覆盖集(点 ...
- 网络流(最大流) HDU 1565 方格取数(1) HDU 1569 方格取数(2)
HDU 1565 方格取数(1) 给你一个n*n的格子的棋盘,每个格子里面有一个非负数.从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的 ...
- HDU 1565 - 方格取数(1) - [状压DP][网络流 - 最大点权独立集和最小点权覆盖集]
题目链接:https://cn.vjudge.net/problem/HDU-1565 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32 ...
- HDU 1565 方格取数(1) 轮廓线dp
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1565 方格取数(1) Time Limit: 10000/5000 MS (Java/Others) ...
随机推荐
- MYSQL-max_binlog_cache_size参数
max_binlog_cache_size 解释:这是设置最大二进制日志的缓存区大小的变量.若处理多语句事务时需要的内存大小比设置值大的话就会提示一个error:Multi-statement tra ...
- HDCMS做异步加载!
控制器的写法: //ajax 请求新闻列表 public function ajaxnewsList(){ $data = Q('sum'); $newsList = M('xinwen')-> ...
- Linux 安装 MantisBT 详解
https://www.cnblogs.com/qdwyg2013/p/6030157.html 在工作中,选用了MantisBT作为公司的BTS工具.MantisBT的作为一款缺陷跟踪管理系统,有以 ...
- Oracle下Delete语句
Delete语句 基本语法: delete from 表名 where 条件 注意事项: 1,如果不使用where子句,将表中所有数据全部删除 delete from test; 2,如果要删除某列的 ...
- C/C++ 开放库
C/C++ 开放库 1.Best C/C++ Network Library 2.A list of open source C++ libraries
- Log4j最简入门及实例
Log4j真的很简单,简单到令人发指的地步.不是要记录日志吗?那就给你一个Log,然后你用Log来写东西就行了,先来一个完整类示例: package test; import org.apache.c ...
- (4.19)sql server中的事务模式(隐式事务,显式事务,自动提交事务)
(4.19)sql server中的事务模式(隐式事务,显式事务,自动提交事务) 1.概念:隐式事务,显式事务,自动提交事务 2.操作:如何设置事务模式 3.存储过程中的事务 XACT_ABORT 1 ...
- python 面向对象 isinstance
查看某个对象是否 这个类实例 是返回True 否则返回False class Foo(object): pass obj = Foo() class Boo(object): pass print(i ...
- python 面向对象 公有属性 用在哪里
公有属性也可以叫做静态字段 如果每个对象都有一个共同的值 , 应该把它设置为公有属性 公有属性使用场景,每个对象中保存相同的东西时,可以使用公有属性 类找公有属性 过程
- centos samba/squid 配置 samba配置 smbclient mount fstab自动挂载samba curl -xlocalhost:3128 www.qq.com squid配置 3128 DNSPOD 第二十七节课
centos samba/squid 配置 samba配置 smbclient mount fstab自动挂载samba curl -xlocalhost:3128 www.qq.com squ ...