Cod sursa(job #2358020)

Utilizator Radu_FilipescuFilipescu Radu Radu_Filipescu Data 27 februarie 2019 20:56:08
Problema Flux maxim de cost minim Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.88 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

ifstream fin( "fmcm.in" );
ofstream fout( "fmcm.out" );

const int NMAX = 400;
const int INF = 2000000000;

int N, M, source, sink;
int cap[NMAX][NMAX], flow[NMAX][NMAX];
int cost[NMAX][NMAX];

vector <int> Ad[NMAX];

int parent[NMAX];
int dist[NMAX];
bool in_q[NMAX];

bool Bf()
{
    for( int i = 1; i <= N; ++i )
      parent[i] = 0;

    for( int i = 1; i <= N; ++i )
      in_q[i] = 0;

    for (int i = 1; i <= N; i++)
      dist[i] = INF;

    queue <int> Q;

    Q.push( source );

    dist[source] = 0;
    in_q[source] = 1;

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

      in_q[u] = 0;

      for( int i = 0; i < Ad[u].size(); ++i )
      {
        int w = Ad[u][i];

        if( dist[u] + cost[u][w] < dist[w] && flow[u][w] != cap[u][w] )
        {
          dist[w] = dist[u] + cost[u][w];
          parent[w] = u;

          if (!in_q[w])
          {
            Q.push(w);
            in_q[w] = 1;
          }
        }
      }
    }

  return dist[sink] != INF;
}

int main()
{
    fin >> N >> M >> source >> sink;

    for( int i = 1; i <= M; i++ )
    {
        int x, y, c, z;

        fin >> x >> y >> c >> z;

        Ad[x].push_back(y);
        Ad[y].push_back(x);
        cap[x][y] = c;
        cap[y][x] = 0;
        cost[x][y] = z;
        cost[y][x] = -z;
    }

    int rez = 0;
    while ( Bf() )
    {
      int minim = INF;
      for( int i = sink; i != source; i = parent[i])
        minim = min(minim, cap[parent[i]][i] - flow[parent[i]][i]);

        for (int i = sink; i != source; i = parent[i])
        {
          flow[parent[i]][i] += minim;
          flow[i][parent[i]] -= minim;

          rez += cost[parent[i]][i] * minim;
        }
    }

    fout << rez;

    return 0;
}