方格取数(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. java中的jdbc操作

    package demo; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedSta ...

  2. Qt:实现子线程发送信号父线程切换图片

    mainwindow.h中代码 #ifndef MAINWINDOW_H#define MAINWINDOW_H #include <QMainWindow>#include " ...

  3. PHP 日常开发过程中的bug集合(持续更新中。。。)

    PHP 日常开发过程中的bug集合(持续更新中...) 在日常php开发过程中,会遇到一些意想不到的bug,所以想着把这些bug记录下来,以免再犯! 1.字符串 '0.00'.'0.0'.'0'  是 ...

  4. pyqt设计

    pyqt是python设计GUI的第三方包 作为一个小白,我觉得这篇博客贼好,我就是按照这个博客写的. 这个博客一共分5步,每一步都特别详细. pyqt 打包exe时遇到的问题(我的python环境是 ...

  5. Java求字符串中出现次数最多的字符

    Java求字符串中出现次数最多的字符  [尊重原创,转载请注明出处]http://blog.csdn.net/guyuealian/article/details/51933611      Java ...

  6. python3爬取”理财大视野”中的股票,并分别写入txt、excel和mysql

    需求:爬取“理财大视野”网站的排名.代码.名称.市净率.市盈率等信息,并分别写入txt.excel和mysql 环境:python3.6.5 网站:http://www.dashiyetouzi.co ...

  7. Python9-进程-day36

    import osfrom multiprocessing import Processimport timedef func(args,args2): print(args,args2) time. ...

  8. socketserver的使用

    socketserver底层也是使用线程实现的并发,直接上代码 # server import socketserver ''' socketserver使用模式: 1 功能类 class Myser ...

  9. 监控网络流量iftop和nethogs安装

    服务器环境是centos7,centos下通常使用iftop,或者nethogs来进行网络流量监控.这2个工具都需要先安装epel,因为这个库通常操作系统是不自带的.那么就先安装epel,使用的命令是 ...

  10. python中json操作了解

    什么是接口? 交换数据 http://openweathermap.org/current json简介 JSON 是存储和交换文本信息的语法.类似 XML JSON 语法是 JavaScript 语 ...