Cod sursa(job #133962)

Utilizator mariusdrgdragus marius mariusdrg Data 10 februarie 2008 04:41:49
Problema Pioni Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.9 kb
 
#include<stdio.h>
#include<algorithm>

using namespace std;

const int maxn = 201;

int st[maxn * maxn * 4],cur[maxn * maxn * 4],ant[maxn * maxn * 4];
int i,j,k;
int mat[maxn * 2 + 4][maxn * 2 + 4];
int a[maxn * 2 + 4][maxn * 2 + 4];
int cupl[maxn * 2 + 4];
int n;
int cmin;
int c[maxn * 2 + 4][maxn * 2 + 4];
int ver[maxn * 2 + 4];
int poz;
int d[maxn * maxn * 4];
bool b[maxn * 2][maxn * 2];


const int inf = 20000000;

bool dr()
{
        st[st[0] = 1] = 0;
        bool move = 1;
        int k = 0;
        for(j = 1;j <= 2 * n + 1; ++j) ver[j] = 0;
        for(j = 1;j <= 2 * n + 1;++j) cur[j] = inf;
        ver[0] = 1;
        while(k != st[0])
        {
                ++k;
                move = 0;
                for(j = 0;j <= 2 * n + 1; ++j)
                {
                        if (c[st[k]][j] == 0) continue;
                        if (cur[j] > cur[st[k]] + a[st[k]][j])
                        {
                                cur[j] = cur[st[k]] + a[st[k]][j];
                                ant[j] = k;
                                if (!ver[j])
                                {
                                        st[++st[0]] = j;
                                        ver[j] = 1;
                                        if (j == 2 * n + 1) poz = st[0];
                                }
                                move = 1;
                        }

                }
                ver[st[k]] = 0;
        }
        if (cur[2 * n + 1] != inf)
        {
                return true;
        }
        return false;
}

void cuplaj()
{
        while(dr())
        {
                int x = poz;
                while(x != 1)
                {
                        c[st[x]][st[ant[st[x]]]] += 1;
                        c[st[ant[st[x]]]][st[x]] -= 1;
                        x = ant[st[x]];
                }
        }
}

int main()
{
        freopen("paznici.in","r",stdin);
        freopen("paznici.out","w",stdout);
        scanf("%d",&n);
   //     printf("%d\n\n",sizeof(a) + sizeof(st) + sizeof(cur) + sizeof(ant) + sizeof(mat) + sizeof(cupl) + sizeof(c) + sizeof(b));
        for(i = 1;i <= 2 * n; ++i)
        {
                for(j = 1;j <= 2 * n; ++j)
                {
                        a[i][j] = inf;
                }
        }
        for(i = 1;i <= n; ++i)
        {
                c[0][i] = 1;
                for(j = 1;j <= n; ++j)
                {
                        c[i][n + j] = 1;
                }
                c[n + i][2 * n + 1] = 1;
        }
        for(i = 1;i <= n; ++i)
                for(j = 1;j <= n; ++j)
                {
                        scanf("%d",&a[j][n + i]);
                        a[n + i][j] = -a[j][n + i];
                }

        cuplaj();

        for(i = 1;i <= n; ++i)
                for(j = n + 1;j <= 2 * n; ++j)
                {
                        if (!c[i][j])
                        {
                                cupl[i] = j;
                                cmin += a[i][j];
                        }
                }

        for(i = 1;i <= n; ++i)
        {
                for(j = 1;j <= n; ++j)
                {
                        mat[i][j] = a[j][cupl[i]] - a[i][cupl[i]];
                }
        }

        for(i = 1;i <= n; ++i)
        {
                for(j = 1;j <= n; ++j)
                {
                        d[j] = inf;
                }
                d[i] = 0;
                st[0] = 0;
                st[++st[0]] = i;
                b[i][i] = 1;
                for(k = 1;k <= st[0]; ++k)
                {
                        for(j = 1;j <= n; ++j)
                        {
                                if (d[j] > d[st[k]] + mat[st[k]][j])
                                {
                                        d[j] = d[st[k]] + mat[st[k]][j];
                                        if (!ver[j])
                                        {
                                                st[++st[0]] = j;
                                                ver[j] = 1;
                                        }
                                }
                                if (j == i && d[j] == d[st[k]] + mat[st[k]][j])
                                {
                                        b[i][st[k]] = 1;
                                }
                        }
                        ver[st[k]] = 0;
                }
        }

        printf("%d\n",cmin);
        for(i = 1;i <= n; ++i)
        {
                st[0] = 0;
                for(j = 1;j <= n; ++j)
                {
                        if (b[i][j])
                        {
                               st[++st[0]] = cupl[j] - n;
                        }
                }
                sort(st + 1,st + st[0] + 1);
                printf("%d",st[0]);
                for(j = 1;j <= st[0]; ++j)
                {
                        printf(" %d",st[j]);
                }
                printf("\n");
        }

        return 0;
}