您的位置:首页 > 其它

洛谷“测试”(这是一场比赛)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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: