嗯,这是关于最大点权独立集与最小点权覆盖集的姿势,很简单对吧,然后开始看题。

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

Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)

Problem Description
给你一个m*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大。
Input
包括多个测试实例,每个测试实例包括2整数m,n和m*n个非负数(m<=50,n<=50)
Output
对于每个测试实例,输出可能取得的最大的和
Sample Input
3 3
75 15 21
75 15 28
34 70 5
Sample Output
188
 
题目思路:
首先我们把所有相邻的格子都连一条边,那么我们的问题就转化成:
这张图上,我们要取得最大的点权(这里的点就相当于带权的格子)集,并且这个点集里的任意两个点之间都没有边(即任意两点不相邻)。
这个即最大点权独立集问题,根据上面的讲解,转化成最小点权覆盖集进行求解。
于是依样画葫芦,先求出所有点权和,记为sum(Wv);
每个相邻的两个格子建边,cap设为INF,方向为从(i+j)是奇数的点到(i+j)是偶数的点;
建立超级源点s,连到所有(i+j)为奇数的点,方向为s出发,cap设为点权;
建立超级汇点t,连到所有(i+j)为偶数的点,方向为到达t,cap设为点权;
这样的话,这个图中,m行n列的方格阵,|V| = mn+2,|E| = m(n-1)+n(m-1) = 2mn-m-n;
我们做最大流求s-t最小割cut.w,便可以得到答案为sum(Wv) - cut.w。
 #include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#define MAX 53*53
#define INF 0x3f3f3f3f
using namespace std;
int m,n,map[][],sum;
int d[][]={{,+},{+,},{,-},{-,}};
struct Edge{
int u,v,c,f;
};
struct Dinic
{
int s,t;
vector<Edge> E;
vector<int> G[MAX];
bool vis[MAX];
int lev[MAX];
int cur[MAX];
void init(int l,int r)
{
E.clear();
for(int i=l;i<=r;i++) G[i].clear();
}
void addedge(int from,int to,int cap)
{
E.push_back((Edge){from,to,cap,});
E.push_back((Edge){to,from,,});
G[from].push_back(E.size()-);
G[to].push_back(E.size()-);
}
bool bfs()
{
memset(vis,,sizeof(vis));
queue<int> q;
q.push(s);
lev[s]=;
vis[s]=;
while(!q.empty())
{
int now=q.front(); q.pop();
for(int i=,_size=G[now].size();i<_size;i++)
{
Edge edge=E[G[now][i]];
int nex=edge.v;
if(!vis[nex] && edge.c>edge.f)
{
lev[nex]=lev[now]+;
q.push(nex);
vis[nex]=;
}
}
}
return vis[t];
}
int dfs(int now,int aug)
{
if(now==t || aug==) return aug;
int flow=,f;
for(int& i=cur[now],_size=G[now].size();i<_size;i++)
{
Edge& edge=E[G[now][i]];
int nex=edge.v;
if(lev[now]+ == lev[nex] && (f=dfs(nex,min(aug,edge.c-edge.f)))>)
{
edge.f+=f;
E[G[now][i]^].f-=f;
flow+=f;
aug-=f;
if(!aug) break;
}
}
return flow;
}
int maxflow()
{
int flow=;
while(bfs())
{
memset(cur,,sizeof(cur));
flow+=dfs(s,INF);
}
return flow;
}
}dinic;
int inmap(int i,int j)
{
if(<=i && i<=m && <=j && j<=n) return (i-)*n+j;
else return ;
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)//m行n列
{
dinic.init(,m*n+);
sum=;
dinic.s=, dinic.t=m*n+;
for(int i=;i<=m;i++)
{
for(int j=;j<=n;j++)
{
scanf("%d",&map[i][j]);
sum+=map[i][j];
int id=(i-)*n+j;
if((i+j)%)
{
for(int k=,_id;k<;k++) if(_id=inmap(i+d[k][],j+d[k][])) dinic.addedge(id,_id,INF);
dinic.addedge(dinic.s,id,map[i][j]);
}
else dinic.addedge(id,dinic.t,map[i][j]);
}
}
printf("%d\n",sum-dinic.maxflow());
}
}

HDU 1569 - 方格取数(2) - [最大点权独立集与最小点权覆盖集]的更多相关文章

  1. HDU 1565 1569 方格取数(最大点权独立集)

    HDU 1565 1569 方格取数(最大点权独立集) 题目链接 题意:中文题 思路:最大点权独立集 = 总权值 - 最小割 = 总权值 - 最大流 那么原图周围不能连边,那么就能够分成黑白棋盘.源点 ...

  2. HDU 1569 方格取数(2)

    方格取数(2) Time Limit: 5000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 15 ...

  3. 网络流(最大流) HDU 1565 方格取数(1) HDU 1569 方格取数(2)

      HDU 1565 方格取数(1) 给你一个n*n的格子的棋盘,每个格子里面有一个非负数.从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的 ...

  4. HDU 1569 方格取数(2) (最小割)

    方格取数(2) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  5. hdu - 1565 方格取数(1) && 1569 方格取数(2) (最大点权独立集)

    http://acm.hdu.edu.cn/showproblem.php?pid=1565 两道题只是数据范围不同,都是求的最大点权独立集. 我们可以把下标之和为奇数的分成一个集合,把下标之和为偶数 ...

  6. HDU 1569 方格取数(2)(最大流最小割の最大权独立集)

    Description 给你一个m*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大.   ...

  7. HDU 1565 - 方格取数(1) - [状压DP][网络流 - 最大点权独立集和最小点权覆盖集]

    题目链接:https://cn.vjudge.net/problem/HDU-1565 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32 ...

  8. [HDU 1565+1569] 方格取数

    HDU 1565 方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  9. HDU 1565&1569 方格取数系列(状压DP或者最大流)

    方格取数(2) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

随机推荐

  1. js語句

    js語句就是告訴瀏覽器要做什麼: js代碼就是js語句序列: js代碼塊就是{}包括的,函數就是一個代碼塊的典型例子: js注釋:單行注釋://,多行注釋:/**/ js對大小寫敏感: js語句可以不 ...

  2. MySQL在Read Uncommitted级别下写操作加X锁

    很多文章认为MySQL在读未提交(Read Uncommitted)的隔离级别下,写操作是不加锁的,然而实际上并不是,在RU级别下,写操作加有X锁. 实践出真知 以前,我也认为RU隔离级别下,写操作不 ...

  3. chapter4 module and port

    如果模块和外界没有交换信号,则可以没有端口列表. 端口隐含声明为wire,如果输出端口需要保存数值,则必须显式声明为reg,如需要保持数值知道下一个时钟边沿

  4. double转换为二进制

    arctan 在verilog 里是1qn或2qn格式,所以要把浮点数转换成1qn格式 1.dec2bin(十进制整数变为二进制) Convert decimal to binary number i ...

  5. java中线程安全和非线程安全的集合

    线程安全 非线程安全 Collection Vector ArrayList.LinkedList HashSet.TreeSet Map HashTable HashMap.TreeMap 字符串 ...

  6. 使用vscode 编写Markdown文件

    markdown简单语法参考下面简单事例: # 一级标题 1. 有序列表1 >1. 有序列表1 >>- *test1* >>- **test2** >>- * ...

  7. JavaScript限制前端页面用户表单输入

    onkeyup事件 onkeyup 事件会在键盘按键被松开时发生. 内容来源:自成e家 1.只能输入数字 <input onkeyup = "value=value.replace(/ ...

  8. DeBruijin HDU - 2894(????????)

    题意: 莫名其妙 看不懂..只能靠别人的题意混日子 a完就懂了  就是 POJ1392  不求第k个了  直接输出这个路径 emm ...就改了一下那个代码 #include <iostream ...

  9. Food HDU - 4292 (结点容量 拆点) Dinic

    You, a part-time dining service worker in your college’s dining hall, are now confused with a new pr ...

  10. hdu 3911 Black And White (线段树 区间合并)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3911 题意: 给你一段01序列,有两个操作: 1.区间异或,2.询问区间最长的连续的1得长度 思路: ...