Cod sursa(job #435777)

Utilizator AstronothingIulia Comsa Astronothing Data 7 aprilie 2010 21:04:37
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.17 kb
#include <iostream>
#include <vector>
#include <fstream>

#define cin f

using namespace std;

int G[101][101];
int H[101][101];
int starred[101][101];
int primed[101][101];
int cr[101],cc[101];
int N;

int getmin(int row)
{
    int minim = G[row][0];
    for(int i=1; i<N; ++i) if(G[row][i]<minim) minim = G[row][i];
    return minim;
}

bool starrable(int row,int col)
{
    for(int i=0; i<N; ++i) if(starred[row][i] || starred[i][col]) return 0;
    return 1;
}

bool contstzcol(int col,int& r)
{
    for(int i=0; i<N; ++i) if(starred[i][col]) {r = i; return 1;}
    return 0;
}

bool contstzrow(int row, int& c)
{
    for(int i=0; i<N; ++i) if(starred[row][i]) { c = i; return 1;}
    return 0;
}

int minval()
{
    int minim = 100000;
    for(int i=0; i<N; ++i) if(!cr[i])
        for(int j=0; j<N; ++j) if(!cc[j])
            if(minim>G[i][j]) minim = G[i][j];
    return minim;
}

void step4();

void step6()
{
    int minvalue = minval();
    for(int i=0; i<N; ++i) if(cr[i])
        for(int j=0; j<N; ++j) G[i][j]+=minvalue;
    for(int i=0; i<N; ++i) if(!cc[i])
        for(int j=0; j<N; ++j) G[j][i]-=minvalue;
    step4();
}

void contprzrow(int row,int& col)
{
    for(int i=0; i<N; ++i) if(primed[row][i]) { col = i; return; }
}

void step3();

void step5(int row,int col)
{
    vector<int> sx,sy;
    vector<int> px,py;
    px.push_back(row);
    py.push_back(col);
    while(contstzcol(col,row))
    {
        sx.push_back(row);
        sy.push_back(col);

        contprzrow(row,col);
        px.push_back(row);
        py.push_back(col);
    }
    for(int i=0; i<sx.size(); ++i) starred[sx[i]][sy[i]] = 0;
    for(int i=0; i<px.size(); ++i) { primed[px[i]][py[i]] = 0; starred[px[i]][py[i]] = 1; }
    for(int i=0; i<N; ++i)
    {
        cr[i] = cc[i] = 0;
        for(int j=0; j<N; ++j) primed[i][j] = 0;
    }
    step3();
}

void step4()
{
    for(int i=0; i<N; ++i) if(!cr[i])
        for(int j=0; j<N; ++j) if(!cc[j])
        {
            if(G[i][j]) continue;
            primed[i][j] = 1;
            int c;
            if(!contstzrow(i,c)) { step5(i,j); return; }
            cr[i] = 1;
            cc[c] = 0;
            j = N;
            i = -1;
        }
    step6();
}

void finished();

void step3()
{
    int covered = 0;
    int aux;
    for(int i=0; i<N; ++i) if(contstzcol(i,aux)) { cc[i] = true; ++covered; }
    if(covered == N) finished();
    else step4();
}

void step2()
{
    for(int i=0; i<N; ++i)
        for(int j=0; j<N; ++j)
        {
            if(G[i][j] == 0 && starrable(i,j)) starred[i][j] = 1;
        }
    step3();
}

void finished()
{
    ofstream f2("cc.out");
    int cost = 0;
    for(int i=0; i<N; ++i)
        for(int j=0; j<N; ++j)
            if(starred[i][j]) { /*cout<<i<<" "<<j<<endl;*/ cost += H[i][j]; }
    f2<<cost;
    return;
}

int main()
{
    ifstream f("cc.in");
    cin>>N;
    for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) { cin>>G[i][j]; H[i][j] = G[i][j]; }

    for(int i=0; i<N; ++i)
    {
        int m = getmin(i);
        for(int j=0; j<N; ++j) G[i][j] -= m;
    }
    step2();



    return 0;
}