Cod sursa(job #1254722)

Utilizator heracleRadu Muntean heracle Data 3 noiembrie 2014 12:02:56
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.73 kb
#include <cstdio>
#include <vector>
#include<queue>
#include<cstring>

FILE* in=fopen("cc.in","r");
FILE* out=fopen("cc.out","w");

const int Q=105,INF=1000000000;

int mm[Q][Q],n;

void brut()
{
    int min=INF;

    for(int q=1; q<=n; q++)
        for(int w=1; w<=n; w++)
            if(w!=q)
            for(int e=1; e<=n; e++)
            if(e!=q && e!=w)
                for(int r=1; r<=n; r++)
                if(r!=q && r!=w && r!=e)
                    for(int t=1; t<=n; t++)
                    if(t!=q && t!=w && t!=e && t!=r)
                    {
                        if(mm[1][q]+mm[2][w]+mm[3][e]+mm[4][r]+mm[5][t]<min)
                            min=mm[1][q]+mm[2][w]+mm[3][e]+mm[4][r]+mm[5][t];
                    }
    fprintf(out,"%d\n",min);
}

struct leg{
    int to,cost;
};

int f[Q+Q][Q+Q],m[Q+Q][Q+Q],c[Q+Q][Q+Q];

bool operator <(const leg &a, const leg &b)
{
    return a.cost>b.cost;
}

std::priority_queue<leg> h;

int frm[Q+Q],cost[Q+Q];

int go[Q+Q];

void actualizare(int x)
{
    int p=2*n+1;
    while(frm[p])
    {
        f[frm[p]][p]+=x;
        f[p][frm[p]]-=x;
        p=frm[p];


    }
    f[frm[p]][p]+=x;
    f[p][frm[p]]-=x;
}

int minim()
{
    int p=2*n+1;
    int rez=INF;

    while(frm[p])
    {
        if(rez>m[frm[p]][p]-f[frm[p]][p])
            rez=m[frm[p]][p]-f[frm[p]][p];
        p=frm[p];
    }
    return rez;
}

bool dijkstra()
{
    while(!h.empty())
        h.pop();

    for(int i=1; i<=n*2+1; i++)
        cost[i]=INF;

    h.push(leg{0,0});

    leg act;
    int actn;

    while(!h.empty())
    {
        act=h.top();
        actn=act.to;
        h.pop();

        if(cost[actn]!=act.cost)
            continue;

        if(actn==2*n+1)
            return 1;

        for(int i=1; i<=2*n+1; i++)
        {
            if(m[actn][i]-f[actn][i]>0 && act.cost+c[actn][i]<cost[i])
            {
                h.push(leg{i,act.cost+c[actn][i]});
                cost[i]=act.cost+c[actn][i];
                frm[i]=actn;
            }
        }
    }

    return 0;
}

int main()
{
    fscanf(in,"%d",&n);

    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
            fscanf(in,"%d",&mm[i][j]);

   // brut();

    for(int i=1; i<=n; i++)
    {
        m[0][i]=1;
    }
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            m[i][j+n]=1;
            c[i][j+n]=mm[i][j];
            c[j+n][i]-=mm[i][j];
        }
    }
    for(int i=1; i<=n; i++)
    {
        m[i+n][2*n+1]=1;
    }

    int min;

    while(dijkstra() )
    {
        min=minim();
        actualizare(min);
    }

    int rez=0;

    for(int i=1; i<=n; i++)
        for(int j=n+1; j<=2*n; j++)
        {
            if(f[i][j]>0)
                rez+=c[i][j];

        }

    fprintf(out,"%d",rez);

    return 0;
}