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块钱,问能携带 ...
随机推荐
- Chapter 1: 随机事件及其概率
1. 随机试验,样本点,样本空间 若试验具有下列特点: 在相同条件下可重复进行 每次试验的可能结果不止一个,且所有可能结果在实验前是已知的 实验前不能确定哪一个结果会发生 则称该试验为随机试验,常记为 ...
- maven添加sqlserver的jdbc驱动包
http://search.maven.org/中没有sqlserver的jdbc驱动,所以需要本地安装sqljdbc的jar包,然后再在pom里面引入 Step 1 在微软官网下载sqljdbc的j ...
- [Python]实现简单决策树
基本思路: 通过香农熵来决定每一层使用哪一种标签做分类,分类后,通过多数表决法来决定该层两个节点的类别.每次消耗一个标签,所以一共需要递归"标签个数"层. # -*- coding ...
- docker tomcat7 dubbo-admin monitor
docker run --name=dubbo_admin9201 -tid -p : -v /home/dubbo/admin:/usr/local/tomcat7/webapps/ROOT cen ...
- Javascript中的字典和散列
function Dictionary() { var items={}; this.set=function (key,value) { items[key]=value; }; this.remo ...
- iscroll 下拉刷新功能
版本号:iscroll4.2.5.js iscroll 版本很有关系 在线: demo链接 有出现白屏的bug,将iscroll版本改成iscroll4.2.5就可以了 html <!DO ...
- 安装升级npm依赖
npm-check 能够自动检索npm包版本,并且提供交互操作界面: 有以下功能: 1.告诉你那些依赖已经过时: 2.在你决定升级时,给你提供依赖包的文档: 3.提示某个依赖没有被你使用: 4.支持全 ...
- CentOS 6.3 安装过程
1.放入光盘 2.安装欢迎界面 进入安装欢迎界面,有四个选项: 1.“Install or upgrade an existing system”:安装或升级现有系统 2. “Install syst ...
- /boot/grub/device.map【设备映射】
grub-install 安装 GRUB 在第一个硬盘的 MBR: # grub-install '(hd0)' grub-install 会先搜寻设备对应的文件(/boot/grub/device. ...
- 求助sublime snippet
单个文件多个snippets不能生效?求助!(已解决) 文件保存路径:F:\work\sublime\Data\Packages\User\completions\xp.sublime-complet ...