NC20213. [JSOI2015]圈地
描述
输入描述
输入第一行包含两个用空格隔开的自然数N和M。
接下来N行,每行M个整数,第i行第j列的整数a描述了位于(i,j)房子的出售信息。
如果a=0,说明强强和南南都不想买这个位置上的房子;
如果a > 0,说明强强想以价格a买这个位置上的房子。
如果a < 0,说明南南想以价格-a买这个位置上的房子。
接下来N-1行,每行M个整数。第i行,第j列的数表示第i行,第j列的房子与第i+1行,第j列的房子之间的墙的造价。
接下来N行,每行M-1个整数。第i行,第j列的数表示第i行,第j列的房子与第i行,第j+1列的房子之间的墙的造价。
1 ≤ N,M ≤ 400,任何价格都不超过1,000
输出描述
输出仅有一行包含一个整数,表示JYY的最大收益。
示例1
输入:
5 5 -3 7 0 0 0 8 0 7 -10 0 0 7 0 1 0 0 0 0 0 0 -8 0 0 2 10 4 50 50 1 50 50 50 1 9 50 50 50 1 1 50 2 50 50 50 50 2 50 50 50 50 50 1 1 50 1 8 1 50 50 50 50 1 50 50 50
输出:
48
C++ 解法, 执行用时: 126ms, 内存消耗: 5568K, 提交时间: 2021-09-06 21:29:27
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<queue> using namespace std; const int N=8e4+10; const int inf=0x3f3f3f3f; int n,m,start,endi,cnt=1,head[N],cur[N],dep[N]; struct node{ int to,next,val; }a[N*6]; inline int read(){ int s=0,w=1; char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-')w=-1; ch=getchar(); } while(ch<='9'&&ch>='0'){ s=s*10+ch-'0'; ch=getchar(); } return s*w; } void addi(int u,int v,int w){ ++cnt; a[cnt].to=v; a[cnt].val=w; a[cnt].next=head[u]; head[u]=cnt; } void add(int u,int v,int w){ addi(u,v,w);addi(v,u,0); } int bfs(int s,int t){ memset(dep,0,sizeof(dep)); memcpy(cur,head,sizeof(head)); queue<int>q; dep[s]=1; q.push(s); while(!q.empty()){ int x=q.front();q.pop(); for(int i=head[x];i;i=a[i].next){ int v=a[i].to; if(a[i].val&&!dep[v])dep[v]=dep[x]+1,q.push(v); } } return dep[t]; } int dfs(int x,int t,int f){ if(x==t)return f; int ans=0; for(int i=cur[x];i&&ans<f;i=a[i].next){ cur[x]=i; int v=a[i].to; int fi=0; if(a[i].val&&dep[v]==dep[x]+1&&(fi=dfs(v,t,min(a[i].val,f-ans)))>0) a[i].val-=fi,a[i^1].val+=fi,ans+=fi; } return ans; } int dinic(int s,int t){ int flow=0; while(bfs(s,t)){ int x=0; if((x=dfs(s,t,1<<30))>0)flow+=x; } return flow; } int main(){ n=read();m=read(); start=0;endi=n*m+1; int sum=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ int x=read(); //int x;cin>>x; int id=m*(i-1)+j; if(x>0)add(start,id,x),sum+=x; if(x<0)add(id,endi,-x),sum+=(-x); } for(int i=1;i<n;i++) for(int j=1;j<=m;j++){ int x=read(); int u=m*(i-1)+j,v=m*i+j; add(u,v,x); add(v,u,x); } for(int i=1;i<=n;i++) for(int j=1;j<m;j++){ int x=read(); int u=m*(i-1)+j,v=m*(i-1)+j+1; add(u,v,x); add(v,u,x); } cout<<sum-dinic(start,endi); return 0; }