Cod sursa(job #133545)

Utilizator silviugSilviu-Ionut Ganceanu silviug Data 8 februarie 2008 21:53:56
Problema Paznici2 Scor Ascuns
Compilator cpp Status done
Runda Marime 3.05 kb
#include <cstdio>
#include <cassert>
#include <vector>
#include <algorithm>

using namespace std;

const int MAX_N = 2 * 256;
const int INF = 1000000000;

int N;
int cost[MAX_N][MAX_N];
int capc[MAX_N][MAX_N];
vector<int> sol[MAX_N];

int dst[MAX_N];
int up[MAX_N];
int per[MAX_N];
bool in_queue[MAX_N];

int source, sink, flow_cost;

void bellman_ford(int start) {
    vector<int> Q[2];
    int crtq = 0;

    for (int i = source; i <= sink; ++i) {
        dst[i] = INF;
    }
    dst[start] = 0;
    Q[0].push_back(start);

    while (!Q[crtq].empty()) {
        memset(in_queue, 0, sizeof(in_queue));
        for (int k = 0; k < (int) Q[crtq].size(); ++k) {
            int crt_nod = Q[crtq][k];
            for (int i = source; i <= sink; ++i) {
                if (capc[crt_nod][i] > 0 &&
                        dst[i] > dst[crt_nod] + cost[crt_nod][i]) {
                    dst[i] = dst[crt_nod] + cost[crt_nod][i];
                    if (in_queue[i] == 0) {
                        in_queue[i] = 1;
                        Q[!crtq].push_back(i);
                    }
                    up[i] = crt_nod;
                }
            }
        }
        Q[crtq].clear();
        crtq = !crtq;
    }
}

void find_path() {
    bellman_ford(source);

    assert(dst[sink] < INF);
    flow_cost += dst[sink];
    for (int i = sink; i != source; i = up[i]) {
        --capc[up[i]][i];
        ++capc[i][up[i]];
    }
}

void restore_capc() {
    for (int i = 1; i <= N; ++i) {
        for (int j = 1; j <= N; ++j) {
            capc[i][j + N] = 1;
            capc[j + N][i] = 0;
        }
    }
    for (int i = 1; i <= N; ++i) {
        capc[source][i] = 1;
        capc[i + N][sink] = 1;
    }
}

int main() {
    freopen("paznici.in", "rt", stdin);
    freopen("paznici.out", "wt", stdout);

    int x;

    scanf("%d", &N);
    source = 0, sink = 2 * N + 1;

    restore_capc();
    for (int i = 1; i <= N; ++i) {
        for (int j = 1; j <= N; ++j) {
            scanf("%d", &x);
            cost[i][j + N] = +x;
            cost[j + N][i] = -x;
        }
    }

    for (int k = 0; k < N; ++k) {
        find_path();
    }
    int optimal_sol = flow_cost;

    for (int i = 1; i <= N; ++i) {
        for (int j = 1; j <= N; ++j) {
            restore_capc();
            capc[i][j + N] = 0;
            capc[source][i] = 0;
            capc[j + N][sink] = 0;

            flow_cost = 0;
            int cost_muchie = cost[i][j + N];
            for (int k = 1; k < N; ++k) {
                find_path();
                if (flow_cost + cost_muchie > optimal_sol) {
                    break;
                }
            }
            assert(flow_cost + cost_muchie >= optimal_sol);
            if (flow_cost + cost_muchie == optimal_sol) {
                sol[j].push_back(i);
            }
        }
    }


    printf("%d\n", optimal_sol);
    for (int i = 1; i <= N; ++i) {
        sort(sol[i].begin(), sol[i].end());
        printf("%d", sol[i].size());
        for (int j = 0; j < (int) sol[i].size(); ++j) {
            printf(" %d", sol[i][j]);
        }
        printf("\n");
    }
    return 0;
}