[Problem Description]
The seating table of Class 11 in Senior High School is an n*m matrix. After a semester, each student and his neighbors have become good friends with each other. This semester will be divided into liberal arts and sciences. Each student has his own value of joy in choosing liberal arts and sciences. If a pair of good friends can choose both liberal arts and Sciences at the same time, they will reap some value of joy. As a computer competition coach, the big boss of scp wants to know how to allocate so that the total happiness of the whole class can be maximized.
[Input Format]
The first line has two positive integers n, m.
Then there are six matrices.
The first matrix is n rows m columns. The number of column j in row i of this matrix indicates that students who are seated in column j of row i choose liberal arts.
The second matrix is n row m column. The number of column j in row i of this matrix represents the delight of students who are seated in column j in row i in choosing science.
The third matrix is n-1 row m column. The number of column j in row i of this matrix indicates that students in column j of row i and in column j of row i+1 choose the additional pleasure value of liberal arts at the same time as those in column j of row i+1.
The fourth matrix is n-1 row m column. The number of column j in row i of this matrix indicates that students in column j of row i and in column j of row i+1 choose the additional pleasure value obtained by science at the same time.
The fifth matrix is n rows m-1 column. The number of column J in row i of this matrix indicates that the students in column J of row i and in column j+1 of row i choose the additional pleasure value of liberal arts at the same time.
The sixth matrix is n row m-1 column. The number of column J in row i of this matrix indicates that students in column J of row i and in column j+1 of row i choose the additional pleasure value obtained by science at the same time.
[Output Format]
Output an integer representing the maximum of the sum of the joy values
[Sample input]
1 2
1 1
100 110
1
1000
[Sample output]
1210
[Sample Notes]
If they both choose, they will get 100 + 110 + 1000.
[Data Size and Agreement]
For data less than 10%, n, m<=4
For data less than 30%, n, m<=8
For data less than 100%, n, m <= 100 ensures that the answer is less than 2 ^ 30.
For 100% of the data, the time limit is 0.5s.
Thought: The main stream on the Internet is the way to solve the equation, I used a way to find the smallest cut.
First of all, considering the minimum cut is to consider the minimum loss, then transform the model. Consider losses. If the source point is set as text and the sink point is set as rational, then each point is connected to the sink point with an edge weighted as a joyful value. Then the relationship between the two points is to set a point, two points to the point with positive and infinite edge weight, and then there is the point to the source or confluence with a edge weight of two points at the same time selected text or at the same time selected joy value. Then run dinic to find the smallest cut. If two points choose one text and one reason, it means cutting off both sides of the selected text at the same time, and choosing the text at the same time, then cutting off the simultaneous selection, and vice versa. Finding the smallest cut means guaranteeing the smallest loss.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define inf 1e9
#define MAXN 100005
using namespace std;
queue<int> q;
struct node
{
int from,to,remain,next;
}e[MAXN*50];
int e_num=-1,point[MAXN];
int deep[MAXN],cur[MAXN];
bool vis[MAXN];
int s,t,ans,n,m;
void add(int from,int to,int remain)
{
++e_num;
e[e_num].from=from;
e[e_num].to=to;
e[e_num].remain=remain;
e[e_num].next=point[from];
point[from]=e_num;
}
bool bfs(int from,int to)
{
memset(deep,0x7f,sizeof(deep));
memset(vis,0,sizeof(vis));
for (int i=0;i<=t+10;i++)
cur[i]=point[i];
deep[from]=0;
vis[from]=1;
q.push(from);
while (!q.empty())
{
int u=q.front();
q.pop();
vis[u]=false;
for (int i=point[u];i!=-1;i=e[i].next)
if (deep[e[i].to]>inf&&e[i].remain)
{
deep[e[i].to]=deep[u]+1;
if (!vis[e[i].to])
{
q.push(e[i].to);
vis[e[i].to]=true;
}
}
}
return deep[to]<inf;
}
int dfs(int from,int to,int limit)
{
int f,flow=0;
if (!limit) return 0;
if (from==to) return limit;
for (int i=cur[from];i!=-1;i=e[i].next)
{
cur[from]=i;
if (deep[e[i].to]==deep[from]+1&&(f=dfs(e[i].to,to,min(limit,e[i].remain))))
{
flow+=f;
limit-=f;
e[i].remain-=f;
e[i^1].remain+=f;
if (!limit) break;
}
}
return flow;
}
void dinic()
{
while (bfs(s,t))
ans+=dfs(s,t,inf);
}
void addedge(int x,int y,int z)
{
add(x,y,z);
add(y,x,0);
}
int main()
{
freopen("nt2011_happiness.in","r",stdin);
freopen("nt2011_happiness.out","w",stdout);
int x,sum=0;
memset(point,-1,sizeof(point));
scanf("%d%d",&n,&m);
s=0;t=n*m*5+100;
for (int i=1;i<=n;i++)//writing
for (int j=1;j<=m;j++)
{
scanf("%d",&x);
sum+=x;
addedge(s,(i-1)*m+j,x);
}
for (int i=1;i<=n;i++) //reason
for (int j=1;j<=m;j++)
{
scanf("%d",&x);
sum+=x;
addedge((i-1)*m+j,t,x);
}
int po=n*m;
for (int i=1;i<=n-1;i++) //writing
for (int j=1;j<=m;j++)
{
scanf("%d",&x);
sum+=x;po++;
addedge(po,(i-1)*m+j,inf);
addedge(po,i*m+j,inf);
addedge(s,po,x);
}
for (int i=1;i<=n-1;i++) //reason
for (int j=1;j<=m;j++)
{
scanf("%d",&x);
sum+=x;po++;
addedge((i-1)*m+j,po,inf);
addedge(i*m+j,po,inf);
addedge(po,t,x);
}
for (int i=1;i<=n;i++) //writing
for (int j=1;j<=m-1;j++)
{
scanf("%d",&x);
sum+=x;po++;
addedge(po,(i-1)*m+j,inf);
addedge(po,(i-1)*m+1+j,inf);
addedge(s,po,x);
}
for (int i=1;i<=n;i++) //reason
for (int j=1;j<=m-1;j++)
{
scanf("%d",&x);
sum+=x;po++;
addedge((i-1)*m+j,po,inf);
addedge((i-1)*m+1+j,po,inf);
addedge(po,t,x);
}
dinic();
printf("%d",sum-ans);
}