Cod sursa(job #209842)

Utilizator vlad_DVlad Dumitriu vlad_D Data 25 septembrie 2008 01:23:43
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.31 kb
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <queue>

using namespace std;
/*#######-MAX FLOW JMENOS-#######*/
#define noduri 256
typedef int matrice[noduri][noduri];
#define INF 99999999


void max_flow_cost(int &flow, int &cost, int sink, int sursa, matrice CAP, matrice P, vector<vector<int> > G) {
     flow = 0; cost = 0;
     //P-rice
     while (1) {
           //find cu cat cresc?
           int BFS[noduri];
           memset(BFS, 0, sizeof(BFS));           
           queue<int> Q; Q.push(sursa);
           BFS[sursa]=INF;
           while (!Q.empty()) {
                 int nod = Q.front(); Q.pop();
                 for (int i = 0; i < G[nod].size(); ++i) {
                     int nod2 = G[nod][i];
                     int aux = CAP[nod][nod2];
                     if (BFS[nod] < aux) aux = BFS[nod];
                     if (aux <= BFS[nod2]) continue;
                     BFS[nod2] = aux;
                     Q.push(nod2);
                     }
                 }
           if (BFS[sink]==0) return; //nu se mai poate creste
           int cresc = BFS[sink];

           flow+=cresc;
           //find the ala cost minim care cresc .. cresc unitatzi
           //find a drum-from sink->source
           BFS[sursa] = -7;
           int pret[noduri];
           for (int i = 0; i < noduri; ++i) pret[i] = INF;           
           pret[sursa] = 0;
           while (!Q.empty()) {Q.pop();}
           Q.push(sursa);
           
           while (!Q.empty()) {
                  int nod = Q.front(); Q.pop();
                  //am un nod
                  for (int i = 0; i < G[nod].size(); ++i) {
                      int nod2 = G[nod][i]; 
                      //baga o conectie de la nod -> nod2
                      if (CAP[nod][nod2] < cresc) continue;
                      if (pret[nod2] <= pret[nod] + P[nod][nod2] * cresc) continue;
                      BFS[nod2] = nod; pret[nod2] = pret[nod] + P[nod][nod2] * cresc;
                      Q.push(nod2);
                      }
                  }
            
           //update
           cost+=pret[sink];
           int nod = sink;
           while (1) {if (BFS[nod]==-7) break; CAP[BFS[nod]][nod]-=cresc; CAP[nod][BFS[nod]]+=cresc; nod = BFS[nod];}
           
           }
     }
/*#######-STOP MAX FLOW JMENOS-#######*/

int n, m;
matrice CAP, P;
vector<vector<int> > G;
int main() {
    freopen("cc.in", "r", stdin);
    freopen("cc.out", "w", stdout);
    cin >> n;
    int i, j;
    G.clear(); G.resize(noduri);
    for (i = 1; i<= n; ++i) 
    for (j = n + 1; j <= 2 * n; ++j) {
        int X;
        cin >> X;
        CAP[i][j] = 1; P[i][j] = X; P[j][i]=-X;
        G[i].push_back(j);
        G[j].push_back(i);
        }
    int sink, sursa;
    sink = 2 * n + 1, sursa = sink + 1;
    for (i = 1; i <= n; ++i) {
        CAP[sursa][i] = 1;
        P[sursa][i]=P[i][sursa]=0;
        G[sursa].push_back(i);
        G[i].push_back(sursa);
        }
    for (i = n + 1; i <= 2 * n; ++i) {
        CAP[i][sink] = 1;
        P[i][sink]=P[sink][i] = 0;
        G[i].push_back(sink);
        G[sink].push_back(i);
        }
    int flow, cost;
    max_flow_cost(flow, cost, sink, sursa, CAP, P, G);
    cout << cost << '\n';
    return 0;
    }