Cod sursa(job #134140)

Utilizator filipbFilip Cristian Buruiana filipb Data 10 februarie 2008 18:59:45
Problema Paznici2 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.43 kb
  #include <stdio.h>  
  #include <string.h>  
     
  #define INF 2000000001  
  #define NMax 2 * 205  
     
  int N, S, D, f[NMax][NMax], cap[NMax][NMax], cost[NMax][NMax], up[NMax];  
  int dist[NMax], q[NMax*NMax], uz[NMax], bst, cnt, is[NMax][NMax];  
  int cuplat, list[205], TOTAL;  
     
  int bellman(int f1, int f2) // fortam sa ia muchia f1-f2  
  {  
       int i, qr, ql;
     
       for (i = S; i <= D; i++)  
           uz[i] = 0, up[i] = 0, dist[i] = INF;  
       dist[0] = 0;  
     
       memset(q, 0, sizeof(q));  
       for (q[qr=ql=0]=S, uz[S]=1; qr <= ql; qr++)  
       {  
           for (i = S; i <= D; i++)  
           {  
               if (q[qr] == f1 && i != f2) continue;  
               if (uz[i] >= D) continue;  
                 
               if (f[q[qr]][i] < cap[q[qr]][i] && dist[q[qr]]+cost[q[qr]][i] < dist[i] && uz[i] < D)  
                   dist[i] = dist[q[qr]] + cost[q[qr]][i],  
                   q[++ql] = i,  
                   uz[i]++,  
                   up[i] = q[qr];  
               if (q[ql] == D)  
                   break;  
           }  
           if (q[ql] == D)  
               break;  
       }  
     
       if (!uz[D])  
           return 0;  
     
       if (f1 != -1 && bst + dist[D] != TOTAL)  
           return 0;  
             
       bst += dist[D];  
       for (i = D; i; i = up[i])  
           f[up[i]][i]++,  
           f[i][up[i]]--;  
      return 1;  
  }  
     
   int main()  
   {  
       int i, j, k;  
         
       freopen("paznici2.in", "r", stdin);
       freopen("paznici2.out", "w", stdout);
     
       scanf("%d", &N);  
       for (i = 1; i <= N; i++)  
           for (j = 1; j <= N; j++)  
           {  
               scanf("%d", &cost[i][j+N]);  
              cost[j+N][i] = -cost[i][j+N];  
              cap[i][j+N] = 1;  
           }  
    
      S = 0; D = 2*N+1;  
      for (i = 1; i <= N; i++)  
          cap[S][i] = cap[N+i][D] = 1;  
    
      for (; bellman(-1, -1); );  
    
      printf("%d\n", bst);  
      TOTAL = bst;  
    
      for (i = 1; i <= N; i++)  
      {  
          for (j = 1, cuplat = 0; j <= N && !cuplat; j++)  
              if (f[i][N+j])  
                 cuplat = j;  
                    
          for (j = 1; j <= N; j++)  
          {  
              if (j == cuplat)  
              {  
                  is[i][j] = 1;  
                  continue;  
              }  
    
              f[N+cuplat][D]--; f[i][N+cuplat]--; f[S][i]--;  
              f[D][N+cuplat]++; f[N+cuplat][i]++; f[i][S]++;  
              bst -= cost[i][N+cuplat];  
              if (bellman(i, j+N))  
              {  
                  cuplat = j;  
                  is[i][j] = 1;  
              }  
              else // punem la loc muchiile scoase  
              {  
                  f[N+cuplat][D]++; f[i][N+cuplat]++; f[S][i]++;  
                  f[D][N+cuplat]--; f[N+cuplat][i]--; f[i][S]--;  
                  bst = TOTAL;  
              }  
                
          }  
     }  
       
     for (i = 1; i <= N; i++)  
     {  
         k = 0;  
         for (j = 1; j <= N; j++)  
             if (is[j][i])
                 list[++k] = j;  
   
         printf("%d ", k);  
         for (j = 1; j < k; j++)  
             printf("%d ", list[j]);  
         printf("%d\n", list[k]);  
     }  
           
    return 0;  
}