方格取数(1)

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7717    Accepted Submission(s): 2911

Problem Description
给你一个n*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
 
Input
包括多个测试实例,每个测试实例包括一个整数n 和n*n个非负数(n<=20)
 
Output
对于每个测试实例,输出可能取得的最大的和
 
Sample Input
3
75 15 21
75 15 28
34 70 5
 
Sample Output
188
 
Author
ailyanlu
 
最小点权覆盖集+最大点权独立集 = 图的总权值
最小点权覆盖集=最大流=最小割
覆盖集、独立集是图论中的相关概念.
而这两个概念在二分图中不是NP问题,所以要把这个图转化为二分图求解。
先建立一个超级源点和一个超级汇点,然后将(x+y)为偶数(或者奇数)的点与超级源点连接,将(x+y)为奇数(或者偶数)的点与超级汇点连接,二分图两边的点相连的权值都记为正无穷,然后对此图求最小割。然后 最大点权独立集 = 总权值 - 最小点权覆盖集
#include <iostream>
#include <queue>
#include<string.h>
#include<algorithm>
#include<stdio.h>
using namespace std;
const int N = ;
const int INF = ;
struct Edge{
int v,w,next;
}edge[N*N];
int head[N];
int level[N];
int mp[N][N];
int n;
void addEdge(int u,int v,int w,int &k){
edge[k].v = v,edge[k].w=w,edge[k].next=head[u],head[u]=k++;
edge[k].v = u,edge[k].w=,edge[k].next=head[v],head[v]=k++;
}
int BFS(int src,int des){
queue<int >q;
memset(level,,sizeof(level));
level[src]=;
q.push(src);
while(!q.empty()){
int u = q.front();
q.pop();
if(u==des) return ;
for(int k = head[u];k!=-;k=edge[k].next){
int v = edge[k].v,w=edge[k].w;
if(level[v]==&&w!=){
level[v]=level[u]+;
q.push(v);
}
}
}
return -;
}
int dfs(int u,int des,int increaseRoad){
if(u==des) return increaseRoad;
int ret=;
for(int k=head[u];k!=-;k=edge[k].next){
int v = edge[k].v,w=edge[k].w;
if(level[v]==level[u]+&&w!=){
int MIN = min(increaseRoad-ret,w);
w = dfs(v,des,MIN);
edge[k].w -=w;
edge[k^].w+=w;
ret+=w;
if(ret==increaseRoad) return ret;
}
}
return ret;
}
int Dinic(int src,int des){
int ans = ;
while(BFS(src,des)!=-) ans+=dfs(src,des,INF);
return ans;
}
int P(int x,int y){
return (x-)*n+y;
}
int dir[][]={,,-,,,,,-};
int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(head,-,sizeof(head));
int tot = ;
int src = ,des = n*n+;
int sum = ;
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
scanf("%d",&mp[i][j]);
sum+=mp[i][j];
if((i+j)%==){
addEdge(src,P(i,j),mp[i][j],tot);
}else{
addEdge(P(i,j),des,mp[i][j],tot);
}
}
}
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
for(int k=;k<=;k++){
int x = i+dir[k][];
int y = j+dir[k][];
if(x<||x>n||y<||y>n) continue;
if((i+j)%==){
addEdge(P(i,j),P(x,y),INF,tot);
}
}
}
}
printf("%d\n",sum-Dinic(,n*n+));
}
return ;
}

hdu 1569

#include <iostream>
#include <queue>
#include<string.h>
#include<algorithm>
#include<stdio.h>
using namespace std;
const int N = ;
const int INF = ;
struct Edge{
int v,w,next;
}edge[N*N];
int head[N];
int level[N];
int mp[][];
int n,m;
void addEdge(int u,int v,int w,int &k){
edge[k].v = v,edge[k].w=w,edge[k].next=head[u],head[u]=k++;
edge[k].v = u,edge[k].w=,edge[k].next=head[v],head[v]=k++;
}
int BFS(int src,int des){
queue<int >q;
memset(level,,sizeof(level));
level[src]=;
q.push(src);
while(!q.empty()){
int u = q.front();
q.pop();
if(u==des) return ;
for(int k = head[u];k!=-;k=edge[k].next){
int v = edge[k].v,w=edge[k].w;
if(level[v]==&&w!=){
level[v]=level[u]+;
q.push(v);
}
}
}
return -;
}
int dfs(int u,int des,int increaseRoad){
if(u==des) return increaseRoad;
int ret=;
for(int k=head[u];k!=-;k=edge[k].next){
int v = edge[k].v,w=edge[k].w;
if(level[v]==level[u]+&&w!=){
int MIN = min(increaseRoad-ret,w);
w = dfs(v,des,MIN);
edge[k].w -=w;
edge[k^].w+=w;
ret+=w;
if(ret==increaseRoad) return ret;
}
}
return ret;
}
int Dinic(int src,int des){
int ans = ;
while(BFS(src,des)!=-) ans+=dfs(src,des,INF);
return ans;
}
int P(int x,int y){
return (x-)*m+y;
}
int dir[][]={,,-,,,,,-};
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(head,-,sizeof(head));
int tot = ;
int src = ,des = n*m+;
int sum = ;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
scanf("%d",&mp[i][j]);
sum+=mp[i][j];
if((i+j)%==){
addEdge(src,P(i,j),mp[i][j],tot);
}else{
addEdge(P(i,j),des,mp[i][j],tot);
}
}
}
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
for(int k=;k<=;k++){
int x = i+dir[k][];
int y = j+dir[k][];
if(x<||x>n||y<||y>m) continue;
if((i+j)%==){
addEdge(P(i,j),P(x,y),INF,tot);
}
}
}
}
printf("%d\n",sum-Dinic(,n*m+));
}
return ;
}

hdu 1565&hdu 1569(网络流--最小点权值覆盖)的更多相关文章

  1. HDU 1853 Cyclic Tour[有向环最小权值覆盖]

    Cyclic Tour Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others)Total ...

  2. Oooooooo AAAAE 【网络流最小点权覆盖】

    Description “Let the bass kick!O-oooooooooo AAAAE-A-A-I-A-U- JO-oooooooooooo AAE-O-A-A-U-U-A- E-eee- ...

  3. The Minimum Cycle Mean in a Digraph 《有向图中的最小平均权值回路》 Karp

    文件链接 Karp在1977年的论文,讲述了一种\(O(nm)\)的算法,用来求有向强连通图中最小平均权值回路(具体问题请参照这里) 本人翻译(有删改): 首先任取一个节点 \(s\) ,定义 \(F ...

  4. HDU 6141 I am your Father!(最小树形图+权值编码)

    http://acm.hdu.edu.cn/showproblem.php?pid=6141 题意: 求最大树形图. 思路: 把边的权值变为负值,那么这就是个最小树形图了,直接套模板就可以解决. 有个 ...

  5. HDU 3488 Tour(最小费用流:有向环最小权值覆盖)

    http://acm.hdu.edu.cn/showproblem.php?pid=3488 题意: 给出n个点和m条边,每条边有距离,把这n个点分成1个或多个环,且每个点只能在一个环中,保证有解. ...

  6. HDU 1863:畅通project(带权值的并查集)

    畅通project Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  7. ZOJ-2342 Roads 二分图最小权值覆盖

    题意:给定N个点,M条边,M >= N-1.已知M条边都有一个权值,已知前N-1边能构成一颗N个节点生成树,现问通过修改这些边的权值使得最小生成树为前N条边的最小改动总和为多少? 分析:由于计算 ...

  8. hdu 1565&&hdu 1569 (最大点权独立集)

    题目意思很明确就是选一些没有相连的数字,使和最大,建成二分图后求最大点权独立集,, #include<stdio.h> #include<string.h> const int ...

  9. Tour HDU - 3488 有向环最小权值覆盖 费用流

    http://acm.hdu.edu.cn/showproblem.php?pid=3488 给一个无源汇的,带有边权的有向图 让你找出一个最小的哈密顿回路 可以用KM算法写,但是费用流也行 思路 1 ...

随机推荐

  1. 14Shell脚本—判断语句

    判断语句 Shell脚本中的条件测试语法可以判断表达式是否成立,若条件成立则返回数字0,否则便返回其他随机数值. 条件测试语法的执行格式为 [ 条件表达式 ],切记,条件表达式两边均应有一个空格. 条 ...

  2. LeetCode之Weekly Contest 93

    第一题:二进制间距 问题: 给定一个正整数 N,找到并返回 N 的二进制表示中两个连续的 1 之间的最长距离. 如果没有两个连续的 1,返回 0 . 示例 1: 输入:22 输出:2 解释: 22 的 ...

  3. python 监控日志

    #需求: #1.每分钟监控服务器日志,ip请求超过200次的,加入黑名单 #1.读文件,获取到每行的内容 open readlines # 178.210.90.90 - - [04/Jun/2017 ...

  4. 如何用纯 CSS 创作一个极品飞车 loader

    效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/MBbEMo 可交互视频 ...

  5. Python基础——文件操作

    写文件 writefile %%writefile ./data/testFile.txt hello python jin tian tian qi bu cuo open覆盖 txt=open(' ...

  6. Java代码中的(解压7z加密版)

    maven:需要加上这个下载这两个包 <dependency> <groupId>net.sf.sevenzipjbinding</groupId> <art ...

  7. LeetCode(306) Additive Number

    题目 Additive number is a string whose digits can form additive sequence. A valid additive sequence sh ...

  8. LeetCode(282) Peeking Iterator

    题目 Given an Iterator class interface with methods: next() and hasNext(), design and implement a Peek ...

  9. 使用Blend的一些问题和技巧

    WPF开发,界面处理首选Blend,如果你开发了两年WPF都没接触过blend(当然这种几率不高),或者你刚接触WPF,可以考虑使用Blend,这货也算得上一个神器,上手也不难.以下有两位讲得不错,大 ...

  10. Python虚拟机之while循环控制结构(三)

    Python虚拟机中的while循环控制结构 在Python虚拟机之if控制流(一)和Python虚拟机之for循环控制流(二)两个章节中,我们介绍了if和for两个控制结构在Python虚拟机中的实 ...