Cod sursa(job #607487)

Utilizator SpiderManSimoiu Robert SpiderMan Data 12 august 2011 12:21:52
Problema Paznici2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.25 kb
# include <algorithm>
# include <cstdio>
# include <cstring>
# include <vector>
# include <queue>
using namespace std;

# define x first
# define y second

const char *FIN = "paznici2.in", *FOU = "paznici2.out";
const int MAX = 405, oo = 0x3f3f3f3f;

vector <int> G[MAX];
int c[MAX][MAX], C[MAX][MAX], F[MAX][MAX], dp[MAX], T[MAX], viz[MAX];
int N, M, S, D;
int cm;

struct comp {
    bool operator () (const int &A, const int &B) {
        return dp[A] > dp[B];
    }
};

priority_queue < int, vector <int>, comp > Q ;

inline void getmin (int &a, int b) {
    a = a < b ? a : b;
}

inline int dijkstra (const int S) {
    memset (T, 0, sizeof (T)), memset (viz, 0, sizeof (viz)), memset (dp, oo, sizeof (dp));
    dp[S] = 0, viz[S] = 1;
    for (Q.push (S); !Q.empty ();) {
        int X = Q.top(); viz[X] = 0; Q.pop ();
        for (vector <int> :: iterator it = G[X].begin (); it != G[X].end (); ++it)
            if (dp[X] + c[X][*it] < dp[*it] && C[X][*it] > F[X][*it]) {
                dp[*it] = dp[X] + c[X][*it], T[*it] = X;
                if (viz[*it] == 0)
                    viz[*it] = 1, Q.push (*it);
            }
    }
    return dp[D] != oo;
}

inline void add (int a, int b) {
    G[a].push_back (b);
    G[b].push_back (a);
}

int main (void) {
    freopen (FIN, "r", stdin);

    scanf ("%d", &N);
    for (int i = 1; i <= N; ++i)
        for (int j = 1; j <= N; ++j) {
            scanf ("%d", c[i] + (j + N));
            c[j + N][i] = -c[i][j + N];
            C[i][j + N] = 1;
            add (i, j + N);
        }
    S = 0, D = 2 * N + 1;
    for (int i = 1; i <= N; ++i) {
        C[S][i] = C[i + N][D] = 1;
        add (S, i), add (D, i + N);
    }
    for (; dijkstra (S); cm += dp[D]) {
        for (int i = D; i != S; i = T[i])
            F[T[i]][i] += 1, F[i][T[i]] -= 1;
    }

    freopen (FOU, "w", stdout);

    printf ("%d\n", cm);
    for (int i = N + 1; i <= N << 1; ++i, printf ("\n")) {
        dijkstra (i);
        int sol = 0;
        for (int j = 1; j <= N; ++j)
            if (c[j][i] + dp[j] == 0)
                ++sol;
        printf ("%d ", sol);
        for (int j = 1; j <= N; ++j)
            if (c[j][i] + dp[j] == 0)
                printf ("%d ", j);
    }
}