HDU 1565:方格取数(1)(最大点权独立集)***
http://acm.hdu.edu.cn/showproblem.php?pid=1565
题意:中文。
思路:一个棋盘,要使得相邻的点不能同时选,问最大和是多少,这个问题就是最大点权独立集。
可以转化为所有的点权 - 最小点权覆盖集(最小割) = 最大点权独立集。
转载两个的定义:这里。
覆盖集(vertex covering set,VCS)是无向图的一个点集,使得该图中所有边都至少有一个端点在该集合内。形式化的定义是点覆盖集为G'VV∈(,)uvE∀∈,满足对于,都有 或成立,即,'uV∈'vV∈'uV∈'vV∈至少一个成立。形象地说是若干个点“覆盖”住了 与它们邻接的边,这些边恰好组成了原边集。
点独立集(vertex independent set,VIS)是无向图的一个点集,使得任两个在该集合中的点在原图中都不相邻。或者说是导出子图为零图(没有边)的点集。形式化的定义是点独立集为,满足对于,都有G'VV∈,'uvV∀∈(,)uvE∉成立。点独立集还有一种等价的定义:点独立集为,满足对于,都有'VV∈'uV∈'vV∈(,)uvE∀∈与不同时成立。
从覆盖集的定义可以看出,求覆盖集就是求最小割(最大流),这个最小点权覆盖集不是S集合就是T集合,最大权独立集就是最小点权覆盖集的补集。
因此把棋盘通过黑白染色:
设一种颜色和S相连(容量为点权),然后用这种颜色去连接相邻另一种颜色(容量为INF),另一种颜色和T相连(容量为点权)。
- #include <cstdio>
- #include <cstring>
- #include <queue>
- using namespace std;
- #define N 510
- #define INF 0x3f3f3f3f
- typedef long long LL;
- struct Edge {
- int v, nxt, cap;
- Edge () {}
- Edge (int v, int nxt, int cap) : v(v), nxt(nxt), cap(cap) {}
- } edge[N*N];
- int head[N], tot, dis[N], cur[N], pre[N], gap[N], n, mp[][], dx[] = {, , , -}, dy[] = {, -, , };
- bool check(int x, int y) {
- if( <= x && x <= n && <= y && y <= n) return true;
- return false;
- }
- void Add(int u, int v, int cap) {
- edge[tot] = Edge(v, head[u], cap); head[u] = tot++;
- edge[tot] = Edge(u, head[v], ); head[v] = tot++;
- }
- int BFS(int S, int T) {
- queue<int> que; que.push(T);
- memset(dis, INF, sizeof(dis));
- memset(gap, , sizeof(gap));
- gap[]++; dis[T] = ;
- while(!que.empty()) {
- int u = que.front(); que.pop();
- for(int i = head[u]; ~i; i = edge[i].nxt) {
- int v = edge[i].v;
- if(dis[v] == INF) {
- dis[v] = dis[u] + ;
- gap[dis[v]]++;
- que.push(v);
- }
- }
- }
- }
- LL ISAP(int S, int T, int n) {
- BFS(S, T);
- memcpy(cur, head, sizeof(cur));
- int u = pre[S] = S, i, index, flow; LL ans = ;
- while(dis[S] < n) {
- if(u == T) {
- flow = INF, index = S; // index = S !!!
- for(i = S; i != T; i = edge[cur[i]].v)
- if(flow > edge[cur[i]].cap) flow = edge[cur[i]].cap, index = i;
- for(i = S; i != T; i = edge[cur[i]].v)
- edge[cur[i]].cap -= flow, edge[cur[i]^].cap += flow;
- ans += flow, u = index;
- }
- for(i = cur[u]; ~i; i = edge[i].nxt)
- if(edge[i].cap > && dis[edge[i].v] == dis[u] - ) break;
- if(~i) {
- pre[edge[i].v] = u; cur[u] = i; u = edge[i].v;
- } else {
- if(--gap[dis[u]] == ) break;
- int md = n;
- for(i = head[u]; ~i; i = edge[i].nxt)
- if(md > dis[edge[i].v] && edge[i].cap > ) md = dis[edge[i].v], cur[u] = i;
- gap[dis[u] = md + ]++;
- u = pre[u];
- }
- }
- return ans;
- }
- int main() {
- while(~scanf("%d", &n)) {
- memset(head, -, sizeof(head)); tot = ;
- int S = , T = n * n + ; LL sum = ;
- for(int i = ; i <= n; i++) for(int j = ; j <= n; j++) scanf("%d", &mp[i][j]), sum += mp[i][j];
- for(int i = ; i <= n; i++) {
- for(int j = ; j <= n; j++) {
- if((i + j) % ) Add(S, (i - ) * n + j, mp[i][j]);
- else Add((i - ) * n + j, T, mp[i][j]);
- for(int k = ; k < ; k++) {
- int nx = i + dx[k], ny = j + dy[k];
- if(check(nx, ny) && (i + j) % ) Add((i - ) * n + j, (nx - ) * n + ny, INF);
- }
- }
- }
- printf("%lld\n", sum - ISAP(S, T, T + ));
- }
- return ;
- }
点覆盖集
(
vertex covering set
,
VCS
)是无向图
的一个点集,使得该图中所有边都至少
有一个端点在该集合内。形式化的定义是点覆盖集为
G
'
V
V
∈
(
,
)
u
v
E
∀
∈
,满足对于
,都有
或
成立,即
,
'
u
V
∈
'
v
V
∈
'
u
V
∈
'
v
V
∈
至少一个成立。形象地说是若干个点“覆盖”住了
与它们邻接的边,这些边恰好组成了原边集。
点独立集
(
vertex independent set
,
VIS
)是无向图
的一个点集,使得任两个在该集合中
的点在原图中都不相邻。或者说是导出子图为零图(没有边)的点集。形式化的定义是点独
立集为
,满足对于
,都有
G
'
V
V
∈
,
'
u
v
V
∀
∈
(
,
)
u
v
E
∉
成立。点独立集还有一种等价的定义:
点独立集为
,满足对于
,都有
'
V
V
∈
'
u
V
∈
'
v
V
∈
(
,
)
u
v
E
∀
∈
与
不同时成立。
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) ...
- HDU 1565 方格取数(1)(最大点权独立集)
http://acm.hdu.edu.cn/showproblem.php?pid=1565 题意: 给你一个n*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格 ...
随机推荐
- 区别JS和DOM对象
<div> <button id="bt" onclick="ChangeColor()">Clike To Change Color& ...
- 【msdn wpf forum翻译】TextBox中文本 中对齐 的方法
原文:[msdn wpf forum翻译]TextBox中文本 中对齐 的方法 原文链接:http://social.msdn.microsoft.com/Forums/en-US/wpf/threa ...
- C# GetFiles
var path = AppDomain.CurrentDomain.BaseDirectory + "Images\\Rooms\\"; // string[] patterns ...
- Interactive Data Display如何显示菜单?
貌似直接跟其它控件一样添加菜单就行了. 不过这个版本已经取消了默认菜单,所有的菜单功能都得自己去实现.
- 修复VirtualBox "This kernel requires the following features not present on the CPU: pae Unable to boot – please use a kernel appropriate for your CPU"(安装深度Linux的时候就需要)
异常处理汇总-开发工具 http://www.cnblogs.com/dunitian/p/4522988.html 修复VirtualBox "This kernel requires ...
- Android零基础入门第77节:Activity任务栈和启动模式
通过前面的学习,Activity的基本使用都已掌握,接下来一起来学习更高级的一些内容. Android采用任务栈(Task)的方式来管理Activity的实例.当启动一个应用时,Android就会为之 ...
- enum 枚举一般用法 dotnet
public enum Demo { [Description("Moning描述")] Moning = , [Description("Afternoon描述&quo ...
- Delphi中,indy控件实现收发邮件的几点学习记录( 可以考虑加入多线程,用多个邮箱做一个邮箱群发器) 转
关于用Delphi中的Indy控件实现收发邮件的几点学习记录 这几天心里颇不宁静,不是因为项目延期,而是因为自己几个月前做的邮件发送程序至今无任何进展,虽然一向谦虚的人在网上发 ...
- Google地图下载工具代码
// // Google Map Tiles Downloader in C# by coolypf // No rights reserved, neither warranty nor guara ...
- 客服端JavaScript线程模型
JavaScript语言核心并不包含任何线程机制,并且客服端JavaScript传统上没有定义任何线程机制.HTML5定义了一种作为后台线程的“WebWorker",但是客服端JavaScr ...