Cod sursa(job #2670996)

Utilizator bogdanvladmihaiBogdan Vlad-Mihai bogdanvladmihai Data 11 noiembrie 2020 10:07:32
Problema Cuplaj maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.97 kb
#include <bits/stdc++.h>

using namespace std;

const int inf = (int)1e9 + 7;
const int max_n = (int)1e4 + 5;

int n, m, e;

int sink, dest;

vector<int> g[max_n];

bool visited[max_n];

int d[max_n], old_d[max_n], new_d[max_n], dad[max_n];

int order[max_n][max_n];

int flow[max_n][max_n], capacity[max_n][max_n], cost[max_n][max_n];

void bellman_ford() {
  queue<int> q;
  q.push(sink);
  visited[sink] = true;
  for (int i = 0; i <= n + m + 1; ++i) {
    d[i] = inf;
  }
  d[sink] = 0;
  while ((int)q.size() > 0) {
    int u = q.front();
    q.pop();
    for (int v : g[u]) {
      if (old_d[v] > old_d[u] + cost[u][v]) {
        old_d[v] = old_d[u] + cost[u][v];
        if (!visited[v]) {
          visited[v] = true;
          q.push(v);
        }
      }
    }
  }
}

bool dijkstra() {
  for (int i = 0; i <= n + m + 1; ++i) {
    d[i] = inf;
  }
  visited[sink] = true;
  d[sink] = new_d[sink] = 0;
  priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
  pq.push(make_pair(0, sink));
  while ((int)pq.size() > 0) {
    int u = pq.top().second;
    int old_c = pq.top().first;
    pq.pop();
    if (old_c != d[u]) {
      continue;
    }
    for (int v : g[u]) {
      if (flow[u][v] < capacity[u][v]) {
        int c = d[u] + cost[u][v] + old_d[u] - old_d[v];
        if (d[v] > c) {
          d[v] = c;
          new_d[v] = new_d[u] + cost[u][v];
          pq.push(make_pair(d[v], v));
          dad[v] = u;
        }
      }
    }
  }
  for (int i = 0; i <= n + m + 1; ++i) {
    old_d[i] = new_d[i];
  }
  return (d[n + m + 1] < inf);
}

int main() {
  int u, v, c, matching = 0, flow_cost = 0;;
  ifstream in("cmcm.in");
  ofstream out("cmcm.out");
  in >> n >> m >> e;
  for (int i = 0; i < e; ++i) {
    in >> u >> v >> c;
    v += n;
    cost[u][v] = c;
    cost[v][u] = -c;
    capacity[u][v] = 1;
    g[u].push_back(v);
    g[v].push_back(u);
    order[u][v] = i + 1;
  }
  sink = 0;
  dest = n + m + 1;
  for (int i = 1; i <= n; ++i) {
    capacity[sink][i] = 1;
    g[sink].push_back(i);
    g[i].push_back(sink);
  }
  for (int i = 1; i <= m; ++i) {
    capacity[i + n][dest] = 1;
    g[dest].push_back(i + n);
    g[i + n].push_back(dest);
  }
  bellman_ford();
  while (dijkstra() == true) {
    int min_flow = inf;
    for (int i = dest; i != sink; i = dad[i]) {
      min_flow = min(min_flow, capacity[dad[i]][i] - flow[dad[i]][i]);
    }
    for (int i = dest; i != sink; i = dad[i]) {
      flow[dad[i]][i] += min_flow;
      flow[i][dad[i]] -= min_flow;
    }
    flow_cost += min_flow * new_d[n + m + 1];
  }
  vector<int> ans;
  for (int i = 1; i <= n; ++i) {
    for (int j = n + 1; j <= n + m; ++j) {
      if (capacity[i][j] == 1 && flow[i][j] == 1) {
        matching += 1;
        ans.push_back(order[i][j]);
      }
    }
  }
  out << matching << " " << flow_cost << "\n";
  for (int val : ans) {
    out << val << " ";
  }
  return 0;
}