洛谷“测试”(这是一场比赛)T3 隔离(最小割)
2017-10-13 18:33
302 查看
题目背景
zx大佬依然秒切。lXz发现世界变得不一样了,他昨天所喜爱的一切都变得一团糟。 他决定造一堵墙把自己和世界隔离开。题目描述
有一个大小为 n×m 的矩阵,在每一个位置造墙付出代价 a[i][j],lXz 站在(x,y), 不允许在(x,y)处造墙,保证(x,y)不在边界上。两个格子如果有一条公共边且都不为墙则 可以互达。边界上的格子,如果不是墙就与外界连通。lXz要选择一些位置造墙,使得从(x,y) 出发无法到达到网格外。他想知道最小的代价是多少。输入输出格式
输入格式:第一行四个正整数 n,m,x,y 意义如题。 接下来 n 行 m 列给出整数 a[i][j]。
输出格式:
一个整数表示最小代价。
输入输出样例
输入样例#1:5 5 3 3
1 1 1 1 1
1 1 5 1 1
1 1 0 8 5
1 1 1 1 1
1 1 1 1 1
输出样例#1:
11
说明
对于 20% 的数据,满足 n×m≤15;对于 50% 的数据,满足 n×m≤50;
对于 100% 的数据,满足 n≤50,m≤50,x≤n,y≤m,0≤a[i][j]<10000。
题解
其实,这应该是一道原题,beijingOI2006,网络流裸题,最小割,因为,其实我们可以把格子拆点,中间连一条容量为a(i,j)的边,然后每个格子和四周连边,容量为inf(这里要注意,拆出来的点一个是入点,一个是出点,边必须从一个入点连向一个出点),然后再把边界上的点向汇点连边,然后源点就是初始位置,直接跑dinic,就过了,这题也没有卡常。代码:
#include<bits/stdc++.h> #define ll long long using namespace std; inline int read(){ int x=0;char ch=' ';int f=1; while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar(); if(ch=='-')f=-1,ch=getchar(); while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); return x*f; } const int inf=0x3f3f3f3f; const int maxn=10001; struct edge{ int from,to,cap,flow; edge(int f,int t,int c,int fl):from(f),to(t),cap(c),flow(fl){} }; struct Dinic{ int n,s,t; int cur[maxn]; int vis[maxn]; int d[maxn]; vector<edge> edges; vector<int> G[maxn]; void init(int n,int s,int t){ this->n=n; this->s=s; this->t=t; edges.clear(); for(int i=0;i<=n;i++){ G[i].clear(); } } inline void addedge(int from,int to,int cap){ edges.push_back(edge(from,to,cap,0)); edges.push_back(edge(to,from,0,0)); int m=edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool bfs(){ memset(vis,0,sizeof(vis)); queue<int> q; q.push(s); vis[s]=1; d[s]=0; while(!q.empty()){ int x=q.front(); q.pop(); for(int i=0;i<G[x].size();i++){ edge &e=edges[G[x][i]]; if(!vis[e.to]&&e.cap>e.flow){ q.push(e.to); vis[e.to]=1; d[e.to]=d[x]+1; } } } return vis[t]; } int dfs(int x,int a){ if(x==t||a==0){ return a; } int f,flow=0; for(int &i=cur[x];i<G[x].size();i++){ edge &e=edges[G[x][i]]; if(d[e.to]==d[x]+1&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0){ e.flow+=f; flow+=f; edges[G[x][i]^1].flow-=f; a-=f; if(a==0)break; } } return flow; } int maxflow(){ int flow=0; while(bfs()){ memset(cur,0,sizeof(cur)); flow+=dfs(s,0x7fffffff); } return flow; } }dinic; int n,m,x,y; int a[51][51]; int main(){ n=read();m=read();x=read();y=read(); int s=(x-1)*m+y,t=0; dinic.init(n*m*2,s,t); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ a[i][j]=read(); if(i!=x||j!=y)dinic.addedge((i-1)*m+j+n*m,(i-1)*m+j,a[i][j]); if(i>1)dinic.addedge((i-1)*m+j,(i-2)*m+j+n*m,inf); if(j>1)dinic.addedge((i-1)*m+j,(i-1)*m+j-1+n*m,inf); if(j<m)dinic.addedge((i-1)*m+j,(i-1)*m+j+1+n*m,inf); if(i<n)dinic.addedge((i-1)*m+j,i*m+j+n*m,inf); } } for(int i=1;i<=n;i++){ dinic.addedge((i-1)*m+1,t,inf); dinic.addedge((i-1)*m+m,t,inf); } for(int i=2;i<m;i++){ dinic.addedge(i,t,inf); dinic.addedge((n-1)*m+i,t,inf); } printf("%d",dinic.maxflow()); return 0; }
相关文章推荐
- 洛谷 P2085 最小函数值(minval)
- 洛谷 一种堆套路 P1631序列合并、P2085最小函数值
- 洛谷P1576 最小花费
- 洛谷P1991 无线通讯网 最小生成树
- USACO历年比赛题目列表,测试数据和解题报告下载
- 输入n个整数,输出其中最小的k个——来自华为OJ平台测试基础篇
- 最小物联网系统设计——给Laravel添加测试
- 【水水水】【洛谷 U4566】赛车比赛
- 洛谷比赛日记
- NAP客户端计算机隔离测试之二
- 洛谷2658 汽车拉力比赛
- 【洛谷】1967 [noip2013]货车运输 最小生成树+LCA
- 使用Profile和Resources Filter隔离测试环境
- hadoop 2.x之HDFS HA讲解之十一测试failover故障转移和隔离、使用sshfence隔离的配置ssh无密钥登陆
- SQL-92 隔离级别理解和测试
- 洛谷比赛『期末考后的休闲比赛2』
- 洛谷 P2774 方格取数问题【最小割】
- Problem Description 输入n(n<100)个数,找出其中最小的数,将它与最前面的数交换后输出这些数。 Input 输入数据有多组,每组占一行,每行的开始是一个整数n,表示这个测试实例的数值的个数,跟着就是n个整数。n=0表示输入的结束,不做处理。 Output 对于每组
- junit--用mock object进行隔离测试(二)
- NAP客户端计算机隔离测试之一 推荐