Cod sursa(job #3148083)

Utilizator vladburacBurac Vlad vladburac Data 29 august 2023 13:04:02
Problema Cuplaj maxim de cost minim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.51 kb
#include <bits/stdc++.h>
using namespace std;
const int NMAX = 602;
const int INF = 1e9;
const int EMAX = 5e4;

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

vector <int> edges[NMAX+1];
int capacity[NMAX+1][NMAX+1];
int cost[NMAX+1][NMAX+1];

pair<int, int> initialEdges[EMAX];

void addEgde( int a, int b, int cap, int c ) {
  edges[a].push_back( b );
  edges[b].push_back( a );
  capacity[a][b] = cap;
  cost[a][b] = c;
  cost[b][a] = -c;
}

int n, source, dest;
int dist[NMAX+1];
queue <int> q;
bool marked[NMAX+1];

void bellman() {
  int i, qfront;
  for( i = 1; i <= n; i++ ) {
    dist[i] = INF;
    marked[i] = false;
  }
  q.push( source );
  dist[source] = 0;
  marked[source] = true;
  while( !q.empty() ) {
    qfront = q.front();
    marked[qfront] = false;
    q.pop();
    for( auto vec: edges[qfront] ) {
      if( dist[vec] > dist[qfront] + cost[qfront][vec] && capacity[qfront][vec] ) {
        dist[vec] = dist[qfront] + cost[qfront][vec];
        if( !marked[vec] ) {
          q.push( vec );
          marked[vec] = true;
        }
      }
    }
  }
}

struct elemInPq {
  int node, cost;
  bool operator<( const elemInPq &x ) const {
    return cost > x.cost;
  }
};
priority_queue <elemInPq> pq;
int fakeDist[NMAX+1], goodDist[NMAX+1];
int parent[NMAX+1];
int viz[NMAX+1];

int edgeWithNewCost( int a, int b ) {
  return goodDist[a] + cost[a][b] - goodDist[b];
}
void dijkstra() {
  int i;
  for( i = 1; i <= n; i++ ) {
    viz[i] = false;
    goodDist[i] = dist[i];
    fakeDist[i] = INF;
    parent[i] = 0;
  }
  pq.push( { source, 0 } );
  fakeDist[source] = dist[source] = 0;
  parent[source] = -1;
  while( !pq.empty() ) {
    auto qfront = pq.top().node;
    //int pret = pq.top().cost;
    pq.pop();
    if( !viz[qfront] ) {
      viz[qfront] = true;
      for( auto vec: edges[qfront] ) {
        if( fakeDist[vec] > fakeDist[qfront] + edgeWithNewCost( qfront, vec ) && capacity[qfront][vec] ) {
          parent[vec] = qfront;
          fakeDist[vec] = fakeDist[qfront] + edgeWithNewCost( qfront, vec );
          dist[vec] = dist[qfront] + cost[qfront][vec];
          pq.push( { vec, fakeDist[vec] } );
        }
      }
    }
  }
}

int nodes1, nodes2, k;
int fmcm() {
  int node, flow, new_flow, minCost, costAlongTheEdges, i;
  bellman();
  dijkstra();
  flow = minCost = 0;
  while( parent[dest] ) {
    node = dest;
    new_flow = INF;
    while( node != source ) {
      new_flow = min( new_flow, capacity[parent[node]][node] );
      node = parent[node];
    }
    node = dest;
    costAlongTheEdges = 0;
    while( node != source ) {
      capacity[parent[node]][node] -= new_flow;
      capacity[node][parent[node]] += new_flow;
      costAlongTheEdges += cost[parent[node]][node];
      node = parent[node];
    }
    flow += new_flow;
    minCost += new_flow * costAlongTheEdges;
    dijkstra();
  }
  fout << flow << " " << minCost << "\n";
  for( i = 0; i < k; i++ ) {
    if( capacity[initialEdges[i].first][initialEdges[i].second + nodes1] == 0 )
      fout << i + 1 << " ";
  }
}

int main() {
  int i, a, b, c;
  fin >> nodes1 >> nodes2 >> k;
  n = nodes1 + nodes2 + 2;
  source = n - 1;
  dest = n;
  for( i = 0; i < k; i++ ) {
    fin >> a >> b >> c;
    initialEdges[i] = { a, b };
    addEgde( a, b + nodes1, 1, c );
  }
  for( i = 1; i <= nodes1; i++ )
    addEgde( source, i, 1, 0 );
  for( i = 1; i <= nodes2; i++ )
    addEgde( nodes1 + i, dest, 1, 0 );
  fmcm();
  return 0;
}