Topcoder SRM558 1000 SurroundingGame
题意:给定一个网格,每个网格有选取代价和占据收益。每个点被占据,需要满足以下两个条件至少一个条件:1.被选取 2.邻近方格都被选取(有公共边被称为邻近) 不一定要占据所有方格,求最大收益。
第一直观感受和文理分科那道题很像,这类肯定用最小割,这种题一般都这样搞,但是建图是个大问题。这道题建出来的图要满足,如果一个点要保留收益,那么要么自己的花费边被割,要么邻近的被割,怎么建呢?
考虑先黑白染色,拆点,然后我们S连向黑色,容量为花费,黑色向自己的分身连收益边,并且黑色向相邻的白色点的分身连INF,黑色分身向白色连INF,白色分身向自己连收益,白色向T连花费。
仔细观察我们发现,确实能满足要求。
这种题一般都是套路,我也不知道怎么就要这么建边,不过可以总结出一些东西,比如一旦有关系,两者之间都会连INF以确保能彼此影响又不会被最小割割中,然后花费和收益,拆点怎么安排就要看具体的题目了。
上代码(与原题的输入不一样,是自己写的)
#include<bits/stdc++.h>
using namespace std;
#define N 25
#define INF 1e9
#define id(x,y) ((x-1)*m+y)
inline int read(){
int x=,f=; char a=getchar();
while(a<'' || a>'') {if(a=='-') f=-; a=getchar();}
while(a>='' && a<='') x=x*+a-'',a=getchar();
return x*f;
}
const int dir[][]={,,-,,,,,-};
int n,m,be[N][N],co[N][N],S,T,P,ans,d[],head[],cur[],cnt;
bool vis[];
queue<int>q;
struct edges{
int to,cap,flow,next;
}e[];
inline void insert(int u,int v,int c){
e[cnt]=(edges){v,c,,head[u]};head[u]=cnt++;
e[cnt]=(edges){u,,,head[v]};head[v]=cnt++;
}
inline bool bfs(){
memset(vis,,sizeof(vis));
vis[S]=; d[S]=; q.push(S);
while(!q.empty()){
int x=q.front(); q.pop();
for(int i=head[x];i>=;i=e[i].next){
if(!vis[e[i].to] && e[i].cap>e[i].flow)
d[e[i].to]=d[x]+,q.push(e[i].to),vis[e[i].to]=;
}
}
return vis[T];
}
int dfs(int x,int a){
if(x==T || !a) return a;
int f,flow=;
for(int& i=cur[x];i>=;i=e[i].next){
if(d[e[i].to]==d[x]+ && (f=dfs(e[i].to,min(a,e[i].cap-e[i].flow)))>)
e[i].flow+=f,flow+=f,e[i^].flow-=f,a-=f;
if(!a) break;
}
return flow;
}
inline int maxflow(){
int flow=;
while(bfs()){
for(int i=S;i<=T;i++) cur[i]=head[i];
flow+=dfs(S,INF);
}
return flow;
}
int main(){
memset(head,-,sizeof(head));
n=read(); m=read();
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
be[i][j]=read(),ans+=be[i][j];
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
co[i][j]=read();
S=; T=*n*m+; P=n*m;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++){
int x,y;
if((i+j)%){
insert(S,id(i,j),co[i][j]),insert(id(i,j),id(i,j)+P,be[i][j]);
for(int k=;k<;k++){
x=i+dir[k][],y=j+dir[k][];
if(x< || x>n || y< || y>m) continue;
insert(id(i,j),id(x,y)+P,INF);
insert(id(i,j)+P,id(x,y),INF);
}
}
else insert(id(i,j)+P,id(i,j),be[i][j]),insert(id(i,j),T,co[i][j]);
}
ans-=maxflow();
printf("%d\n",ans);
return ;
}
Topcoder SRM558 1000 SurroundingGame的更多相关文章
- TopCoder SRM 558 Div 1 - Problem 1000 SurroundingGame
传送门:https://284914869.github.io/AEoj/558.html 题目简述 一个人在一个n * m棋盘上玩游戏,想要占领一个格子有两个方法: 在这个格子放一个棋子. 这个 ...
- 经典数学问题<手电过河问题>的动态解法--问题规模扩展至任意大小
非常有趣的一件事是今天在TopCoder的1000分题里面发现了这道经典数学问题. Notes - In an optimal solution ...
- TopCoder SRM 560 Div 1 - Problem 1000 BoundedOptimization & Codeforces 839 E
传送门:https://284914869.github.io/AEoj/560.html 题目简述: 定义"项"为两个不同变量相乘. 求一个由多个不同"项"相 ...
- Topcoder Srm 673 Div2 1000 BearPermutations2
\(>Topcoder \space Srm \space 673 \space Div2 \space 1000 \space BearPermutations2<\) 题目大意 : 对 ...
- Topcoder Srm 671 Div2 1000 BearDestroysDiv2
\(>Topcoder \space Srm \space 671 \space Div2 \space 1000 \space BearDestroysDiv2<\) 题目大意 : 有一 ...
- TopCoder SRM500 Div1 1000 其他
原文链接https://www.cnblogs.com/zhouzhendong/p/SRM500-1000.html SRM500 Div1 1000 设 \(v_1,v_2,\cdots ,v_9 ...
- TopCoder SRM502 Div1 1000 动态规划
原文链接https://www.cnblogs.com/zhouzhendong/p/SRM502-1000.html SRM502 Div1 1000 题意 从 [0,n-1] 中选择 k 个不同的 ...
- TopCoder[SRM513 DIV 1]:Reflections(1000)
Problem Statement Manao is playing a new game called Reflections. The goal of the game is trans ...
- TopCoder SRM 642 Div.2 1000 --二分+BFS
题意: 给你一张图,N个点(0~N-1),m条边,国王要从0到N-1,国王携带一个值,当走到一条边权大于此值的边时,要么不走,要么提升该边的边权,提升k个单位花费k^2块钱,国王就带了B块钱,问能携带 ...
随机推荐
- highcharts 去掉Highcharts.com链接
将credits属性设为false credits: { enabled: false },
- C#序列化及反序列化Json对象通用类JsonHelper
当今的程序界Json大行其道.因为Json对象具有简短高效等优势,广受广大C#码农喜爱.这里发一个序列化及反序列化Json对象通用类库,希望对大家有用. public class JsonHelper ...
- Github上关于iOS的各种开源项目集合(强烈建议大家收藏,查看,总有一款你需要)
下拉刷新 EGOTableViewPullRefresh - 最早的下拉刷新控件. SVPullToRefresh - 下拉刷新控件. MJRefresh - 仅需一行代码就可以为UITableVie ...
- 浏览器禁止js打开新窗口
在项目中,有个需求是需要ajax获取新地址,然后去打开该页面地址,这样会被浏览器拦截,可以采取以下方式:1.再ajax请求先前,先创建一个新窗口 var newTab = window.open('' ...
- ImageList图标左边有黑色竖线
ImageList图标左边有黑色竖线, 原因 ImageList颜色深度太小引起的,解决方案,把颜色深度调成Depth32Bit 默认: 修改为: 结果: 备注:根据文件获得文件的系统图标: Icon ...
- 剑指offer七:两个链表的第一个公共结点
输入两个链表,找出它们的第一个公共结点. import java.util.*; public class Solution { public ListNode FindFirstCommonNode ...
- linux启动流程及自定义gurb
linux 启动流程 POST BIOS(boot sequence) 所选择的启动设备次序的MBR中是否有引导程序, ----> MBR(bootloader) 提供内核列表 -------& ...
- 转:Eclipse快捷键 10个最有用的快捷键
Eclipse快捷键 10个最有用的快捷键 Eclipse中10个最有用的快捷键组合 一个Eclipse骨灰级开发者总结了他认为最有用但又不太为人所知的快捷键组合.通过这些组合可以更加容易的浏览源代 ...
- 转:OSGi 入门篇:生命周期层
OSGi 入门篇:生命周期层 前言 生命周期层在OSGi框架中属于模块层上面的一层,它的运作是建立在模块层的功能之上的.生命周期层一个主要的功能就是让你能够从外部管理应用或者建立能够自我管理的应用(或 ...
- Exit code from container executor initialization is : 24 ExitCodeException exitCode=24: Configuration file ../etc/hadoop/container-executor.cfg not found.
/etc/hadoop/conf的软链接(/etc/hdfs/conf)不正确,应该是/etc/yarn/conf