Pagini recente » Cod sursa (job #93098) | Cod sursa (job #3259744) | Cod sursa (job #1434843) | Cod sursa (job #2641350) | Cod sursa (job #133545)
Cod sursa(job #133545)
#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;
}