Pagini recente » Cod sursa (job #2252131) | Cod sursa (job #2137077) | Cod sursa (job #1989460) | Cod sursa (job #2533574) | Cod sursa (job #40823)
Cod sursa(job #40823)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define NMAX 128
#define INFINIT 20000
FILE *f = fopen("cc.in","rt"), *g = fopen("cc.out","wt");
long int a[NMAX][NMAX],n,i,j,nrl[NMAX],marc[NMAX],marl[NMAX],ok,mat[NMAX][NMAX];
long int cadru[NMAX][NMAX],barat[NMAX][NMAX],ord[NMAX],nrz[NMAX];
long int hashL[NMAX],hashC[NMAX];
void citire()
{
fscanf(f,"%ld",&n);
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{fscanf(f,"%ld",&a[i][j]);
mat[i][j]=a[i][j];
}
}
void first()
{
long int minc[NMAX],minl[NMAX];
memset(minc,0,sizeof(minc));
memset(minl,0,sizeof(minl));
//pe coloane
for (i=1;i<=n;i++)
minc[i]=a[1][i];
for (i=2;i<=n;i++)
for (j=1;j<=n;j++)
if (a[i][j]<minc[j]) minc[j]=a[i][j];
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
a[i][j]=a[i][j]-minc[j];
//pe linii
for (i=1;i<=n;i++)
minl[i]=INFINIT;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if (a[i][j]<minl[i]) minl[i]=a[i][j];
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
a[i][j]=a[i][j]-minl[i];
}
int cmp(const void *x, const void *y)
{
return nrz[* (long int *) x] - nrz[* (long int *) y];
}
void second()
{
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if ((a[i][j]==0)&&((cadru[i][j]==0)&&(barat[i][j]==0))) nrz[i]++;
for (i=1;i<=n;i++)
ord[i]=i;
qsort(ord,n+1,sizeof(long int),cmp);
ok=0;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if ((a[ord[i]][j]==0)&&(hashC[j]==0)) {cadru[ord[i]][j]=1;hashC[j]=1;hashL[ord[i]]=1;ok++;break;}
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if (hashL[i]||hashC[j]) barat[i][j]=1;
}
void third()
{
long int ok1;
memset(marc,0,sizeof(marc));
memset(marl,0,sizeof(marl));
//marchez liniile
for (i=1;i<=n;i++)
marl[i]=!hashL[i];
ok=1;
while (ok)
{
//marchez coloanele
ok=0;
for (i=1;i<=n;i++)
if (marl[i])
for (j=1;j<=n;j++)
if ((barat[i][j])&&(marc[j]==0)) {marc[j]=1;ok=1;}
//mai marchez niste linii
for (i=1;i<=n;i++)
if (marc[i])
for (j=1;j<=n;j++)
if ( (cadru[j][i]) && (marl[j]==0) ) marl[j]=1;
}
}
void forth()
{
long int min;
min=INFINIT;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if (((marl[i]==1)&&(marc[i]==0))&&(a[i][j]<min)) min=a[i][j];
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
if (marc[j]==0) a[i][j]-=min;
if (marl[j]==0) a[i][j]+=min;
}
}
void print()
{
long int s=0;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if (cadru[i][j]) s+=mat[i][j];
fprintf(g,"%ld\n",s);
}
//STATUS: daca poate gasi solutia din prima atunci merge corect altfel nu
//TODO: THIRD() AND FORTH() : DEBUG :((
int main()
{
citire();
first();
second();
while (ok<n)
{
third();
forth();
second();
}
print();
fclose(f);
fclose(g);
return 0;
}