Cod sursa(job #134141)

Utilizator gigi_becaliGigi Becali gigi_becali Data 10 februarie 2008 19:03:12
Problema Paznici2 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.34 kb
using namespace std;
#include <cstdio>
#include <string>
#include <queue>
#define maxn 402
#define oo 0x3f3f3f3f



int cost[maxn][maxn],c[maxn][maxn],C[maxn][maxn],d[maxn],t[maxn];
int source, sink;
int n;
int l[maxn], r[maxn];
bool use[maxn];
int S[201][201];

void read()
{
  freopen("paznici2.in","r",stdin);
  scanf("%d\n", &n);
  int i, j, p;
  source=0;
  sink=2*n+1;

  for(i=1;i<=n;++i)
    for(j=1;j<=n;++j)
      {
	scanf("%d ", &p);
	cost[i][j+n]=p;
	cost[j+n][i]=-p;
	c[i][j+n]=1;
	C[i][j+n]=1;
	
      }
  
  for(i=1;i<=n;++i) cost[source][i]=0, c[source][i]=1, C[source][i]=1;
  for(i=n+1;i<=(n<<1);++i) cost[i][sink]=0, c[i][sink]=1, C[i][sink]=1;

}

inline int bellman()
{
  queue<int>Q;

  int u, i;
  memset(d, oo, sizeof(d));
  memset(t, 0, sizeof(t));

  d[source]=0;

  Q.push(source);
  
  while(!Q.empty())
    {
      u=Q.front();
      Q.pop();

      for(i=source;i<=sink;++i)
	if(c[u][i])
	  if(d[u]+cost[u][i]<d[i])
	    {
	      d[i]=d[u]+cost[u][i];
	      Q.push(i);
	      t[i]=u;
	    }
    }

  if(t[sink]==0) return 0;

  for(i=sink; i!=source; i=t[i]) 
    {
      c[t[i]][i]=0;
      c[i][t[i]]=1;
    }
  return 1;

}

inline int bell(int A, int B)
{
  queue<int>Q;

  int u, i;
  memset(d, oo, sizeof(d));
  memset(t, 0, sizeof(t));
  bool isq[maxn];
  memset(isq, 0, sizeof(isq));

  d[source]=0;

  Q.push(source);
  isq[source]=1;

  while(!Q.empty())
    {
      u=Q.front();
      //      isq[u]=0;
      Q.pop();
      if(u==A) continue;
      if(u==B) continue;

      for(i=source;i<=sink;++i)
	if(c[u][i])
	  {
	    if(i==A) continue;
	    if(i==B) continue;
	    if(d[u]+cost[u][i]<d[i])
	      {
		d[i]=d[u]+cost[u][i];
		//if(!isq[i]){ 
		  Q.push(i);
		  // isq[i]=1;}
		t[i]=u;
	      }
	  }
    }

  /*
  for(i=source;i<=sink;++i) printf("%d ", d[i]);
  printf("\n");
  */
  if(t[sink]==0) return 0;
  
  
  for(i=sink; i!=source; i=t[i]) 
    {
      c[t[i]][i]=0;
      c[i][t[i]]=1;
    }
  return 1;

}



void solve()
{
  
  while(bellman());

  int i, j,sol=0;

  for(i=1;i<=n;++i)
    for(j=n+1;j<sink;++j)
      if(!c[i][j]) 
	{
	  l[j]=i;
	  r[i]=j;
	  //  printf("%d %d\n", i, j-n);
	  sol+=cost[i][j];
	}
  // printf("%d\n", sol);

  int k, t,s=0;
  for(i=1;i<n;++i)
    for(j=n+1;j<sink;++j)
      {
	memset(c, 0, sizeof(c));
	memset(r,0, sizeof(r));
	
	//	memcpy(c, C, sizeof(C));
	
	for(k=source;k<=sink;++k)
	  for(t=source;t<=sink;++t) c[k][t]=C[k][t];

	//	for(k=source;k<=sink;++k) c[i][k]=c[k][i]=c[j][k]=c[k][j]=0;
	//c[j+n][i]=0;
	while(bell(i,j));
	s=cost[i][j];
	//	printf("%d %d__\n", i, j);
	
	r[i]=j;
	for(k=1;k<=n;++k)
	  for(t=n+1;t<sink;++t)
	    if(!c[k][t])
	      {
		if(k==i && t==j) continue;
		//	if(k==j && t==i) continue;
		s+=cost[k][t],r[k]=t;
	      }
	//printf("%d %d\n", s, sol);
	
	if(s==sol) 
	  {
	    for(k=1;k<=n;++k) if(r[k]>n) r[k]-=n;
	    for(k=1;k<=n;++k){/* printf("%d ", r[k]);*/S[k][r[k]]=1;}
	    //    printf("\n");
	  }

      }

  int nr;
  
  freopen("paznici2.out","w",stdout);


  printf("%d\n", sol);
  for(i=1;i<=n;++i)
    {
      nr=0;
      for(j=1;j<=n;++j) if(S[i][j]) ++nr;
      printf("%d ", nr);
      for(j=1;j<=n;++j) if(S[i][j]) printf("%d ", j);

      printf("\n");
    }


  /*
  int flow=0;
  int ok=1;
  while(ok)
    {
      ok=0;
      memset(use, 0, sizeof(use));
      for(i=1;i<=n;++i)
	if(!r[i]) pairup(i), ok=1;
    }
  */
}

int main()
{
  read();
  solve();
  return 0;
}