Cod sursa(job #1836875)

Utilizator cella.florescuCella Florescu cella.florescu Data 28 decembrie 2016 19:18:47
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.12 kb
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 6e2 + 3;
const int INF = 0x3f3f3f3f;

vector <int> g[MAXN];
queue <int> q;
int flow[MAXN][MAXN], cost[MAXN][MAXN], cap[MAXN][MAXN], edge[MAXN][MAXN];
int father[MAXN], inq[MAXN], dist[MAXN];

inline void add_edg(int x, int y, int z) {
  g[x].push_back(y);
  g[y].push_back(x);
  cost[x][y] = z;
  cost[y][x] = -z;
  cap[x][y] = 1;
}

int bellman(int s, int d) {
  int node;
  memset(dist, INF, sizeof dist);
  inq[s] = 1;
  q.push(s);
  dist[s] = 0;
  while (q.empty() == 0) {
    node = q.front();
    q.pop();
    inq[node] = 0;
    for (auto it : g[node])
      if (flow[node][it] < cap[node][it] && dist[it] > dist[node] + cost[node][it]) {
        dist[it] = dist[node] + cost[node][it];
        father[it] = node;
        if (inq[it] == 0) {
          inq[it] = 1;
          q.push(it);
        }
      }
  }
  return (dist[d] < INF);
}

inline int minimum(int A, int B) {
  if (A < B)
    return A;
  return B;
}

int main()
{
    int n, m, e, x, y, z, fl, node, maxflow, mincost;
    ifstream fin("cmcm.in");
    fin >> n >> m >> e;
    for (int i = 0; i < e; ++i) {
      fin >> x >> y >> z;
      add_edg(x, y + n, z);
      edge[x][y + n] = i + 1;
    }
    fin.close();
    for (int i = 1; i <= n; ++i)
      add_edg(0, i, 0);
    for (int i = n + 1; i <= n + m; ++i)
      add_edg(i, n + m + 1, 0);
    maxflow = mincost = 0;
    while (bellman(0, n + m + 1)) {
      for (node = n + m + 1, fl = INF; node > 0; node = father[node])
        fl = minimum(fl, cap[father[node]][node] - flow[father[node]][node]);
      for (node = n + m + 1; node > 0; node = father[node]) {
        flow[father[node]][node] += fl;
        flow[node][father[node]] -= fl;
      }
      maxflow += fl;
      mincost += fl * dist[n + m + 1];
    }
    ofstream fout("cmcm.out");
    fout << maxflow << " " << mincost << '\n';
    for (int i = 1; i <= n; ++i)
      for (int j = n + 1; j <= n + m; ++j)
        if (cap[i][j] && flow[i][j])
          fout << edge[i][j] << " ";
    fout << '\n';
    fout.close();
    return 0;
}