P1935 [National Team] Rodeo minimum cut plan

  

Title Description

Recent real estate GDOI (Group of Dumbbells Or Idiots) to get a piece of land development from NOI (Nuts Old Idiots) hands. It is understood that this land is a rectangular area, an aspect can be divided into smaller blocks of N × M areas. GDOI requires that these areas are divided into commercial and industrial areas to develop. Depending on the terrain, each small area to build commercial and industrial areas can achieve different economic value. More specifically, for the region j-th column of the i-th row, the construction of the business district will be Aij income, build industrial zones will be Bij earnings. Further the different regions can be linked to additional benefits, i.e., if the region (i, J) of adjacent (neighboring lattice refers to a common two sides) with a k-th block (k obviously not more than 4) type is different from (i , j) of the area, this area can be increased k × Cij benefits. After investigation Professor Tiger.S, payoff matrix A, B, C already know. Can you help find a GDOI maximum benefits program it?

Input Format

Input of the first two acts of integers, respectively, and M is a positive integer N, respectively, the number of rows and columns of regions;

2 to N + 1 columns, each row of M integers, A payoff matrix represents the business district;

The second N + 2 to 2N + 1 columns, each row integers M, B represents the payoff matrix industrial areas;

2N + 2 of the 3N + 1 rows of M integers, represents additional revenue adjacent matrix C.

Output Format

Output only one line containing an integer value for the maximum benefit.

Sample input and output

Input # 1
3 3
1 2 3
4 5 6
7 8 9
9 8 7
6 5 4
3 2 1
1 1 1
1 3 1
1 1 1
Output # 1
81 


meaning of the questions: There nm points each point A can be connected to the weights aij even B can also get additional rights bij weights value: around each point of the camp and he chose not to have the same k a (apparently less than 4) then the obtained weights k * cij


If the same then a very simple and small crop m as

it can be converted adjacent points can be selected to be the same additional weights
only as a matrix board staining AB connecting the black dots in FIG manner opposite to the original (the minimum cut is obtained no effect)
then converted to the same point adjacent camp to obtain weights

While FIG small and it has been transformed crop m or do a little of this problem is the same as long as you can (no matter what the election camp)

can be considered in good faith that the question of voting

adjacent dots and a two-way side because if these two points will each contribute two different values , so the two edges between points bidirectional edge, the edge weight is the sum of these two values

#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f
const int N=4e5+44;
const int M=4e6+54;
int d[N];
struct edge {
    int to, next, w;
} e[M << 1];
int head[N],cur[N],cnt = 1;
void add(int x, int y, int z) {
    e[++cnt] = (edge){y, head[x], z};
    head[x] = cnt;
    e[++cnt] = (edge){x, head[y], 0};
    head[y] = cnt;
}
void ins(int x,int y,int a,int b)
{
    add(x,y,b-a);
    d[x]-=a;
    d[y]+=a;
}

int level[N];
bool bfs(int s, int t) {
    memset(level, 0, sizeof level);
    queue<int> q;
    level[s] = 1;
    q.push(s);
    while (!q.empty()) {
        int pos = q.front();q.pop();
        for (int i = head[pos]; i; i = e[i].next) {
            int nx = e[i].to;
            if (!e[i].w || level[nx]) continue;
            level[nx] = level[pos] + 1;
            q.push(nx);
        }
    }
    return level[t];
}
int dfs(int s, int t, int flow) {
    if(s==t||flow==0)return flow;

    int f,ret = 0;
    for (int &i = cur[s],v; i; i = e[i].next) {
         v = e[i].to;
        if (level[v] == level[s] + 1 && (f=dfs(v,t,min(flow,e[i].w)))>0) {
            e[i].w -= f;
            e[i ^ 1].w += f;
            flow -= f;
            ret += f;
            if(!flow)break;
        }
    }
    return ret;
}
int dinic(int s, int t) {
    int ret = 0;
    while (bfs(s, t)) memcpy(cur,head,sizeof cur),ret += dfs(s, t, inf);
    return ret;
}
int n,m,s,t,a,b,c,sum,S,T;

int id(int x,int y)
{
    return (x-1)*m+y;
}

int mp[200][200];
int main()
{
    cin>>n>>m;
    s=n*m+100;t=s+1;

    rep(i,1,n)
    rep(j,1,m)
    if( (i+j)&1 )
    scanf("%d",&a),add(s,id(i,j),a),sum+=a;
    else scanf("%d",&a),add(id(i,j),t,a),sum+=a;

    rep(i,1,n)
    rep(j,1,m)
    if( !((i+j)&1) )
    scanf("%d",&a),add(s,id(i,j),a),sum+=a;
    else scanf("%d",&a),add(id(i,j),t,a),sum+=a;

    rep(i,1,n)
    rep(j,1,m)scanf("%d",&mp[i][j]);

    int dx[]={1,-1,0,0};
    int dy[]={0,0,1,-1};

    rep(i,1,n)
    rep(j,1,m)
    {
        if( (i+j)&1 )continue;

        rep(k,0,3)
        {
            int x=i+dx[k];
            int y=j+dy[k];
            if(x<1||y<1||x>n||y>m)continue;

            add(id(i,j),id(x,y),mp[i][j]+mp[x][y]);
            add(id(x,y),id(i,j),mp[i][j]+mp[x][y]);
            sum+=mp[i][j]+mp[x][y];
        }
    }
    cout<<sum-dinic(s,t);

    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/bxd123/p/11328457.html