Pagini recente » Cod sursa (job #1773060) | Profil LicaAna | Cod sursa (job #499848) | Cod sursa (job #1853876) | Cod sursa (job #135983)
Cod sursa(job #135983)
#include <cstdio>
#include <queue>
using namespace std;
#define MAXN 405
int N, cst[MAXN][MAXN], c[MAXN][MAXN];
int val[MAXN];
int cup[MAXN];
char good[MAXN][MAXN];
#define IN(i) (i)
#define OUT(i) ((i) + N)
int SRC, DST;
int F = 0, CST = 0;
int d[MAXN], p[MAXN]; char in[MAXN];
queue<int> Q;
inline void update( int nod, int Cst, int par )
{
if (Cst >= d[nod])
return;
// Cst < d[nod]
d[nod] = Cst;
p[nod] = par;
if (!in[nod])
Q.push(nod),
in[nod] = 1;
}
inline int bf()
{
memset( d, 0x3f, sizeof(d) );
memset( p, -1, sizeof(p) );
d[SRC] = 0; Q.push(SRC); in[SRC] = 1;
for (; !Q.empty(); Q.pop())
{
int i = Q.front(), type = 0;
if (1 <= i)
type = 1;
if (N + 1 <= i)
type = 2;
if (i == DST)
type = 3;
if (type == 0 || type == 2)
for (int j = 1; j <= N; j++)
if (c[i][j])
update( j, d[i] + cst[i][j], i );
if (type == 1)
for (int j = N + 1; j <= N + N; j++)
if (c[i][j])
update( j, d[i] + cst[i][j], i );
if (type == 2)
if (c[i][DST])
update( DST, d[i] + cst[i][DST], i );
in[i] = 0;
}
return (d[DST] != 0x3f3f3f3f);
}
inline void bfRight( int S )
{
memset( d, 0x3f, sizeof(d) );
memset( p, -1, sizeof(p) );
d[S] = 0; Q.push(S); in[S] = 1;
for (; !Q.empty(); Q.pop())
{
int i = Q.front(), type = 1;
if (N + 1 <= i)
type = 2;
if (type == 1)
for (int j = N + 1; j <= N + N; j++)
if (!c[i][j])
update( j, d[i] + cst[j][i], i );
if (type == 2)
for (int j = 1; j <= N; j++)
if (!c[i][j])
update( j, d[i] + cst[j][i], i );
in[i] = 0;
}
}
int main()
{
freopen("paznici2.in", "rt", stdin);
freopen("paznici2.out", "wt", stdout);
scanf("%d", &N); SRC = 0; DST = N + N + 1;
for (int i = 1; i <= N; i++)
{
c[SRC][ IN(i) ] = 1;
c[ OUT(i) ][DST] = 1;
for (int j = 1; j <= N; j++)
{
scanf("%d", cst[ IN(i) ] + OUT(j));
cst[ OUT(j) ][ IN(i) ] = -cst[ IN(i) ][ OUT(j) ];
c[ IN(i) ][ OUT(j) ] = 1;
}
}
for (; bf(); F++, CST += d[DST])
for (int j = DST; j != SRC; j = p[j])
c[ p[j] ][j]--,
c[j][ p[j] ]++;
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++)
if (!c[ IN(i) ][ OUT(j) ])
{
cup[ IN(i) ] = OUT(j);
cup[ OUT(j) ] = IN(i);
break;
}
printf("%d\n", CST);
for (int i = 1; i <= N; i++)
{
bfRight( cup[ IN(i) ] );
//trebuie afisat invers...
for (int j = 1; j <= N; j++)
if (d[ OUT(j) ] + cst[ IN(i) ][ OUT(j) ] - cst[ IN(i) ][ cup[ IN(i) ] ] == 0)
good[j][i] = 1;
}
for (int i = 1; i <= N; i++)
{
int Nr = 0;
for (int j = 1; j <= N; j++)
Nr += good[i][j];
printf("%d", Nr);
for (int j = 1; j <= N; j++)
if (good[i][j])
printf(" %d", j);
printf("\n");
}
return 0;
}