HDU 4862 Jump starting point for any maximum weight K chain cover

You can start off from an arbitrary starting point for most K times

You can select each hop or jump from the right (x1, y1) to jump to (x2, y2) is the energy consumption Manhattan distance -1

But if the numbers start and end points of the grid of each transition is the same as X, then you will get X energy

Q. Can you jump K times just dance through the whole map (each point is after a) the maximum if possible energy output

Solution: same as first cover strand and the minimum point of each split into the left point and the out-point is a point to the right point is then built according to the meaning of the title edge

It is important how we limit up to take-off times this condition K solution is Add (S, S ', K, 0) and S' towards the right of each point not even a capacity of 1 0 of the cost side

Why is it up to the K chain? Consider the smallest chain cover = | V | - That match after match point number (point) was not the right match is to be regarded as the starting point of a chain so right has not been matched several points we must have a few chain

So we can only have the right to limit K nodes can not be matched

#include<bits/stdc++.h>
#define reg register
using namespace std;
typedef long long ll;
typedef int JQK;
const int INF = 0x7f7f7f7f;
const int MAXN = 505, MAXM = 13000;
int Head[MAXN], cur[MAXN], to[MAXM << 1], nxt[MAXM << 1], f[MAXM << 1], ed = 1;
int S, T, MAXP, MAXF, pre[MAXN];
JQK lev[MAXN], mono[MAXM << 1];
bool exist[MAXN];
inline void RR(int &x) {
        char c;
        bool sign = false;
        for (c = getchar(); c < '0' || c > '9'; c = getchar())
                if (c == '-') {
                        sign = true;
                }
        for (x = 0; c >= '0' && c <= '9'; c = getchar()) {
                x = x * 10 + c - '0';
        }
        sign && (x = -x);
}
void addedge(int u, int v, int cap, JQK val) {
        //cout<<u<<" "<<v<<" "<<cap<<" "<<val<<endl;
        to[++ed] = v;
        nxt[ed] = Head[u];
        Head[u] = ed;
        f [ed] = ch;
        mono [-ed] = val;
        to[++ed] = u;
        nxt[ed] = Head[v];
        Head[v] = ed;
        f[ed] = 0;
        mono [-ed] = - 1 * val;
        return ;
}
BOOL BFS () {
         you and;
        queue<int> q;
        for (int i = 0; i <= MAXP + 1; i++) {
                exist[i] = 0;
                lev [i] = INF;
        }
        leu [S] = the [S] = 0 ;
        q.push(S);
        while (q.size()) {
                u = q.front();
                q.pop();
                exist[u] = false;
                for (int i = Head[u]; i; i = nxt[i])
                        if (f[i] && lev[u] + mono[i] < lev[to[i]]) {
                                Lev [to [i]] = lev [u] + mono [i];
                                pre[to[i]] = i;
                                if (!exist[to[i]]) {
                                        exist[to[i]] = true;
                                        q.push(to[i]);
                                }
                        }
        }
        for (int i = 0; i <= MAXP + 1; i++) {
                cur[i] = Head[i];
        }
        return lev[T] != INF;
}
JQK Increase () {
        JQK delta = INF;
        for (int i = pre[T]; i; i = pre[to[i ^ 1]])
                if (f[i] < delta) {
                        delta = f[i];
                }
        for (int i = pre[T]; i; i = pre[to[i ^ 1]]) {
                f[i] -= delta;
                f[i ^ 1] += delta;
        }
        MAXF += delta;
        return delta * lev[T];
}
JQK MCMF() {
        JQK years = 0 ;
        memset(exist, false, sizeof(exist));
        while (BFS()) {
                years + = Augment ();
        }
        return years;
}
void init(int x123, int y123) {
        MAXF = 0;
        for (int i = 0; i <= MAXP; i++) {
                Head[i] = 0;
        }
        ed = 1;
        S = x123;
        T = y123;
        return ;
}
char f1[15][15];
int ff[15][15];
int num[15][15];
int main() {
        int TNT;
        int n, m, K;
        RR(TNT);
        for (int cas = 1; cas <= TNT; cas++) {
                int sum = 0;
                RR(n), RR(m), RR(K);
                for (int i = 1; i <= n; i++) {
                        scanf("%s", f1[i] + 1);
                        for (int j = 1; j <= m; j++) {
                                ff [i] [j] = f1 [i] [j] - ' 0 ' ;
                        }
                }
                for (int i = 1; i <= n; i++) {
                        for (int j = 1; j <= m; j++) {
                                whether [i] [j] = ++ am;
                        }
                }
                MAXP = 2 * sum + 3;
                init(2 * sum + 2, 2 * sum + 3);
                addedge(S, S - 1, K, 0);
                for (int i = 1; i <= n; i++) {
                        for (int j = 1; j <= m; j++) {
                                addedge(S, num[i][j], 1, 0);
                                addedge(sum + num[i][j], T, 1, 0);
                                addedge(S - 1, sum + num[i][j], 1, 0);
                        }
                }
                for (int i = 1; i <= n; i++) {
                        for (int j = 1; j <= m; j++) {
                                int now = ff[i][j];
                                for (int k = i + 1; k <= n; k++) {
                                        int now2 = ff[k][j];
                                        int add = (now == now2) ? now : 0;
                                        addedge(num[i][j], sum + num[k][j], 1, -(add - (k - i - 1)));
                                }
                                for (int k = j + 1; k <= m; k++) {
                                        int now2 = ff[i][k];
                                        int add = (now == now2) ? now : 0;
                                        addedge(num[i][j], sum + num[i][k], 1, -(add - (k - j - 1)));
                                }
                        }
                }
                printf("Case %d : ", cas);
                if (K < min(n, m)) {
                        printf("-1\n");
                        continue;
                }
                int anser = MCMF();
                if (MAXF != sum) {
                        printf("-1\n");
                } else {
                        printf("%d\n", -anser);
                }
        }
        return 0;
}

 

 

 

Guess you like

Origin www.cnblogs.com/Aragaki/p/11756434.html