Cod sursa(job #133598)

Utilizator pauldbPaul-Dan Baltescu pauldb Data 9 februarie 2008 02:25:23
Problema Paznici2 Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.55 kb
#include <stdio.h>  
#include <vector>  
#include <algorithm>  
  
using namespace std;  
  
#define maxn 410  
#define maxm 210  
#define inf 100000000  
#define S 0  
#define D 2*n+1  
#define maxx 40010  
  
double ct[maxn];  
int l;  
int s[maxx];  
int n,rez,found;  
int b[maxn][maxn],aux[maxn][maxn];  
char sol[maxm][maxm];  
vector <int> a[maxn];  
int g[maxn],from[maxn],cost[maxn];  
char c[maxn][maxn],f[maxn][maxn];  
  
int BellmanFord()  
{  
    int i,j,k,magic,stop = 0;  
  
    for (i=S;i<=D;i++) cost[i] = inf;  
    cost[S] = 0;  
  
    if (n > 25) magic = 15;  
    else magic = n+15;  
  
    for (k = 0;k <= magic && !stop;k++)   
    {  
        stop = 1;  
        for (i=S;i<=D;i++)   
            for (j=0;j<g[i];j++)  
                if (c[i][a[i][j]] - f[i][a[i][j]] > 0 && cost[i] + b[i][a[i][j]]< cost[a[i][j]])  
                {  
                    cost[a[i][j]] = cost[i] + b[i][a[i][j]];  
                    from[a[i][j]] = i;  
                    stop = 0;  
                }  
    }  
  
    if (cost[D] != inf)  
    {  
        i = D;  
        while (i!=S)  
        {  
            f[from[i]][i]++;  
            f[i][from[i]]--;  
            i = from[i];  
        }  
    }  
  
    return cost[D];  
}  
  
int Flux(int x,int y)  
{  
    int sum = 0,i,j;  
    found = 1;  
  
    if (x != inf)  
    {  
        for (i=1;i<=n;i++)  
        {  
            b[i][y] = b[x][i+n] = inf;  
            b[y][i] = b[i+n][x] = -inf;  
        }  
  
        b[x][y] = aux[x][y];  
        b[y][x] = aux[y][x];  
    }  
      
    for (i=1;i<=n;i++)   
    {  
        sum += BellmanFord();  
        if (x != inf && sum > rez) break;  
    }  
  
    if (x != inf)  
        for (i=1;i<=n;i++)  
        {  
            b[i][y] = aux[i][y];  
            b[x][i+n] = aux[x][i+n];  
            b[y][i] = aux[y][i];  
            b[i+n][x] = aux[i+n][x];  
        }  
  
    if (sum == rez || x == inf)  
        for (i=1;i<=n;i++)  
            for (j=1;j<=n;j++)   
                if (f[i][j+n]) sol[i][j] = 1;  
  
    for (i=S;i<=D;i++)  
        for (j=S;j<=D;j++) f[i][j] = 0;  
  
    return sum;  
}  
  
int main()  
{  
    freopen("paznici2.in","r",stdin);  
    freopen("paznici2.out","w",stdout);  
  
    scanf("%d ",&n);  
  
    int i,j;  
  
    for (i=1;i<=n;i++)  
        for (j=1;j<=n;j++)   
        {  
            scanf("%d ",&b[i][j+n]);  
            s[++l] = b[i][j+n];  
            b[j+n][i] = - b[i][j+n];  
        }  
  
    sort(s+1,s+l+1);  
    ct[30] = 15;  
    ct[50] = 3;  
    ct[80] = 0.75;  
    ct[150] = 0.15;  
    ct[170] = 0.15;  
    ct[200] = 0.1;  
  
    for (i=S;i<=D;i++)  
        for (j=S;j<=D;j++) aux[i][j] = b[i][j];  
  
    for (i=1;i<=n;i++)  
    {  
        for (j=1;j<=n;j++)   
        {  
            a[i].push_back(j+n);  
            a[j+n].push_back(i);  
            c[i][j+n] = 1;  
        }  
  
        a[i].push_back(S);  
        a[S].push_back(i);  
        c[S][i] = 1;  
        a[D].push_back(i+n);  
        a[i+n].push_back(D);  
        c[i+n][D] = 1;  
    }  
  
    for (i=S;i<=D;i++) g[i] = a[i].size();  
  
    rez = Flux(inf,inf);  
  
    printf("%d\n",rez);  
  
    for (i=1;i<=n;i++)  
        for (j=1;j<=n;j++)   
            if (!sol[i][j])   
                if (n < 30 || b[i][n+j] < s[int(n*ct[n])]) Flux(i,n+j);  
  
    for (i=1;i<=n;i++)  
    {  
        int x = 0;  
        for (j=1;j<=n;j++) x += sol[j][i];  
  
        printf("%d ",x);  
  
        for (j=1;j<=n;j++)   
            if (sol[j][i]) printf("%d ",j);  
        printf("\n");  
    }  
  
    return 0;  
}