洛谷传送门 LOJ传送门

太空飞行计划问题一样,这依然是一道最大权闭合图问题

“骑士共存问题”是“方格取数问题”的弱化版,本题解不再赘述“骑士共存问题”的做法

分析题目,如果我们能把所有方格的数都给取上,那么总和是一个定值$sum$

而题目要求我们取的数不能相邻,我们要想办法最大化$\sum$取的数$-\sum$没取的数

现在我们找到了一种取数方案,那么$\sum$取的数一定能填补上$\sum$没取的数,而且剩下的数总和$>0$,这样,方案才是有收益的

这不就是最大权闭合图的模型吗?

把每个格子拆成两个点,分别向源点和汇点连边,流量为它的权值,每个格子向四周连流量为$inf$的边

最小割割掉了用于填补的部分,用$sum-$最小割就是净收益了

方格取数问题:

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N1 2510
#define M1 30100
#define ll long long
#define dd double
#define inf 0x3f3f3f3f
using namespace std; int gint()
{
int ret=,fh=;char c=getchar();
while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
return ret*fh;
}
int n,m,nm,S,T;
int p[N1],c[N1];
int xx[]={-,,,},yy[]={,,,-};
struct Edge{
int head[N1],to[M1<<],nxt[M1<<],flow[M1<<],cte;
void ae(int u,int v,int F)
{
cte++; to[cte]=v; flow[cte]=F;
nxt[cte]=head[u]; head[u]=cte;
}
}e; int que[M1],hd,tl,dep[N1],cur[N1];
int bfs()
{
int x,j,v;
memset(dep,-,sizeof(dep)); memcpy(cur,e.head,sizeof(cur));
hd=,tl=; que[++tl]=S; dep[S]=;
while(hd<=tl)
{
x=que[hd++];
for(j=e.head[x];j;j=e.nxt[j])
{
v=e.to[j];
if(dep[v]==-&&e.flow[j]>)
dep[v]=dep[x]+, que[++tl]=v;
}
}
return dep[T]!=-;
}
int dfs(int x,int limit)
{
int j,v,flow,ans=; if(x==T||!limit) return limit;
for(j=cur[x];j;j=e.nxt[j])
{
cur[x]=j; v=e.to[j];
if( dep[v]==dep[x]+ && (flow=dfs(v,min(e.flow[j],limit))) )
{
limit-=flow; ans+=flow;
e.flow[j]-=flow; e.flow[j^]+=flow;
if(!limit) break;
}
}
return ans;
}
int Dinic()
{
int mxflow=;
while(bfs())
mxflow+=dfs(S,inf);
return mxflow;
} int a[N1];
int check(int x,int y){
if(x<||y<||x>n||y>m) return ; return ;}
int id(int x,int y){ return (x-)*m+y; } int main()
{
scanf("%d%d",&n,&m); nm=n*m;
int i,j,k,d,da,db,sum=,ans; S=*nm+,T=*nm+; e.cte=;
for(i=;i<=n;i++) for(j=;j<=m;j++)
{
d=id(i,j); a[d]=gint(); sum+=a[d];
e.ae(S,d,a[d]), e.ae(d,S,);
e.ae(d+nm,T,a[d]), e.ae(T,d+nm,);
}
for(i=;i<=n;i++) for(j=;j<=m;j++)
{
da=id(i,j);
for(k=;k<;k++)
if(check(i+xx[k],j+yy[k]))
{
db=id(i+xx[k],j+yy[k])+nm;
e.ae(da,db,inf), e.ae(db,da,);
}
}
ans=sum-Dinic();
printf("%d\n",(sum-ans)/+ans);
return ;
}

骑士共存问题: 只需要把点权改成1 加几个特判就行了

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define L1 205
#define N1 80050
#define M1 400010
#define ll long long
#define dd double
#define inf 0x3f3f3f3f
using namespace std; int gint()
{
int ret=,fh=;char c=getchar();
while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
return ret*fh;
}
int n,m,nn,S,T;
int p[N1],c[N1];
int xx[]={-,-,,,,,-,-},yy[]={,,,,-,-,-,-};
struct Edge{
int head[N1],to[M1<<],nxt[M1<<],flow[M1<<],cte;
void ae(int u,int v,int F)
{
cte++; to[cte]=v; flow[cte]=F;
nxt[cte]=head[u]; head[u]=cte;
}
}e; int que[N1],hd,tl,dep[N1],cur[N1];
int bfs()
{
int x,j,v;
memset(dep,-,sizeof(dep)); memcpy(cur,e.head,sizeof(cur));
hd=,tl=; que[++tl]=S; dep[S]=;
while(hd<=tl)
{
x=que[hd++];
for(j=e.head[x];j;j=e.nxt[j])
{
v=e.to[j];
if(dep[v]==-&&e.flow[j]>)
dep[v]=dep[x]+, que[++tl]=v;
}
}
return dep[T]!=-;
}
int dfs(int x,int limit)
{
int j,v,flow,ans=; if(x==T||!limit) return limit;
for(j=cur[x];j;j=e.nxt[j])
{
cur[x]=j; v=e.to[j];
if( dep[v]==dep[x]+ && (flow=dfs(v,min(e.flow[j],limit))) )
{
limit-=flow; ans+=flow;
e.flow[j]-=flow; e.flow[j^]+=flow;
if(!limit) break;
}
}
return ans;
}
int Dinic()
{
int mxflow=;
while(bfs())
mxflow+=dfs(S,inf);
return mxflow;
} int mp[L1][L1];
int check(int x,int y){
if(x<||y<||x>n||y>n||mp[x][y]) return ; return ;}
int id(int x,int y){ return (x-)*n+y; } int main()
{
scanf("%d%d",&n,&m); nn=n*n;
int i,j,k,d,da,db,x,y,sum=,ans; S=*nn+,T=*nn+; e.cte=;
for(i=;i<=m;i++) x=gint(), y=gint(), mp[x][y]=;
for(i=;i<=n;i++) for(j=;j<=n;j++)
{
if(mp[i][j]) continue; d=id(i,j); sum++;
e.ae(S,d,), e.ae(d,S,);
e.ae(d+nn,T,), e.ae(T,d+nn,);
}
for(i=;i<=n;i++) for(j=;j<=n;j++)
{
if(mp[i][j]) continue; da=id(i,j);
for(k=;k<;k++)
if(check(i+xx[k],j+yy[k]))
{
db=id(i+xx[k],j+yy[k])+nn;
e.ae(da,db,inf), e.ae(db,da,);
}
}
ans=sum-Dinic();
printf("%d\n",(sum-ans)/+ans);
return ;
}

[网络流24题] 方格取数问题/骑士共存问题 (最大流->最大权闭合图)的更多相关文章

  1. AC日记——[网络流24题]方格取数问题 cogs 734

    734. [网络流24题] 方格取数问题 ★★☆   输入文件:grid.in   输出文件:grid.out   简单对比时间限制:1 s   内存限制:128 MB «问题描述: 在一个有m*n ...

  2. Cogs 734. [网络流24题] 方格取数问题(最大闭合子图)

    [网络流24题] 方格取数问题 ★★☆ 输入文件:grid.in 输出文件:grid.out 简单对比 时间限制:1 s 内存限制:128 MB «问题描述: 在一个有m*n 个方格的棋盘中,每个方格 ...

  3. [网络流24题] 方格取数问题(cogs 734)

    «问题描述:在一个有m*n 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意2 个数所在方格没有公共边,且取出的数的总和最大.试设计一个满足要求的取数算法.«编程任务:对于给定的方格棋 ...

  4. luogu2774 [网络流24题]方格取数问题 (最小割)

    常见套路:棋盘黑白染色,就变成了一张二分图 然后如果选了黑点,四周的白点就不能选了,也是最小割的套路.先把所有价值加起来,再减掉一个最少的不能选的价值,也就是割掉表示不选 建边(S,黑点i,v[i]) ...

  5. XTU 二分图和网络流 练习题 C. 方格取数(1)

    C. 方格取数(1) Time Limit: 5000ms Memory Limit: 32768KB 64-bit integer IO format: %I64d      Java class ...

  6. hdu 3657 最大点权独立集变形(方格取数的变形最小割,对于最小割建图很好的题)

    转载:http://blog.csdn.net/cold__v__moon/article/details/7924269 /* 这道题和方格取数2相似,是在方格取数2的基础上的变形. 方格取数2解法 ...

  7. 【网络流24题】No.19 负载平衡问题 (费用流)

    [题意] G 公司有 n 个沿铁路运输线环形排列的仓库, 每个仓库存储的货物数量不等. 如何用最少搬运量可以使 n 个仓库的库存数量相同.搬运货物时,只能在相邻的仓库之间搬运. 输入文件示例input ...

  8. 【网络流24题】No.7 试题库问题 (最大流,二分图多重匹配)

    [题意] 假设一个试题库中有 n 道试题. 每道试题都标明了所属类别. 同一道题可能有多个类别属性.现要从题库中抽取 m 道题组成试卷.并要求试卷包含指定类型的试题. 试设计一个满足要求的组卷算法. ...

  9. 【Luogu】P2045方格取数加强版(最小费用最大流)

    题目链接 通过这题我学会了引诱算法的行为,就是你通过适当的状态设计,引诱算法按照你想要它做的去行动,进而达到解题的目的. 最小费用最大流,首先将点拆点,入点和出点连一条费用=-权值,容量=1的边,再连 ...

随机推荐

  1. 实践一些js中的prototype, __proto__, constructor

    <!DOCTYPE html> <html> <head> <title>ExtJs</title> <meta http-equiv ...

  2. Go语言net/http 解读.

    Http包提供实现HTTP客户端和服务端的方法与函数. Get.Head.Post.PostForm配合使用实现HTTP请求: resp, err := http.Get("http://e ...

  3. 手把手实现Java权限(1)-Shiro介绍

    功能介绍 Authentication :身份认证/登录.验证用户是不是拥有对应的身份:  Authorization :授权,即权限验证.验证某个已认证的用户是否拥有某个权限:即推断用  户能否做事 ...

  4. 好纠结啊,JeeWx商业版本号和开源版本号有什么差别呢?

    好纠结啊,JeeWx商业版本号和开源版本号有什么差别呢? JeeWx开源版本号是一套基础微信开发平台.有基础的微信菜单.素材管理.微信对接等基础功能,适合于开发人员学习研究. JeeWx商业版本号是一 ...

  5. Android执行时ART载入OAT文件的过程分析

    在前面一文中,我们介绍了Android执行时ART,它的核心是OAT文件.OAT文件是一种Android私有ELF文件格式,它不仅包括有从DEX文件翻译而来的本地机器指令.还包括有原来的DEX文件内容 ...

  6. 用Java做的类似皇家守卫战的游戏

    最近因为数据结构的课设缘故,所以用Java做了一款类似皇家守卫战(本人最钟情的一款PC兼手游的塔防游戏)的游戏.现在把这个游戏放出来,可以下载下来 玩耍 学习,代码中我也做了大量的注释.(运行游戏得带 ...

  7. H3BPM表单设计器公式设计参考

    表单设计器公式设计参考 整体说明 Ø 公式以javascript方式解析,最终支持JS语法或计算方式: Ø 公式变量以数据项为主,以{}符号表示数据项,例如数据项A,表示为{A}:如果是子表中的数据项 ...

  8. B - Soldier and Bananas

    Problem description A soldier wants to buy w bananas in the shop. He has to pay k dollars for the fi ...

  9. Javascript中数组重排序方法详解

    在数组中有两个可以用来直接排序的方法,分别是reverse()和sort().下面通过本文给大家详细介绍,对js 数组重排序相关知识感兴趣的朋友一起看看吧. 1.数组中已存在两个可直接用来重排序的方法 ...

  10. Codeforces Round #446

    Greed #include<stdio.h> #include<string.h> #include<stdlib.h> #include<vector&g ...