Pagini recente » Cod sursa (job #2739463) | Cod sursa (job #2748243) | Cod sursa (job #3180463) | Cod sursa (job #350592) | Cod sursa (job #2892294)
#include <bits/stdc++.h>
#define MAX_N 300
#define MAX_M 300
#define MAX_VT (MAX_N + MAX_M + 2)
#define MULT (1 << 30)
using namespace std;
int muchie[MAX_VT + 1][MAX_VT + 1];
struct FLOW {
struct elemPQ {
int u, cost;
bool operator < (const elemPQ &a) const {
return cost > a.cost;
}
};
int s, t, vt;
int maxFlow, minCost;
bool inQ[MAX_VT], vis[MAX_VT];
int cap[MAX_VT][MAX_VT], cost[MAX_VT][MAX_VT], flux[MAX_VT][MAX_VT], parent[MAX_VT], realCost[MAX_VT], newCost[MAX_VT], fakeCost[MAX_VT];
vector <int> edges[MAX_VT];
void add_edge( int u, int v, int c, int z ) {
edges[u].push_back( v );
edges[v].push_back( u );
cap[u][v] = c;
cost[u][v] = z;
cost[v][u] = -z;
}
void bellman() {
int u;
queue <int> q;
for ( u = 0; u < vt; u++ )
newCost[u] = MULT;
for ( u = 0; u < vt; u++ )
inQ[u] = false;
newCost[s] = 0;
q.push( s );
while ( !q.empty() ) {
u = q.front();
q.pop();
inQ[u] = false;
for ( int v: edges[u] ) {
if ( newCost[u] + cost[u][v] < newCost[v] && flux[u][v] < cap[u][v] ) {
parent[v] = u;
newCost[v] = newCost[u] + cost[u][v];
if ( !inQ[v] ) {
q.push( v );
inQ[v] = true;
}
}
}
}
}
bool dijkstra() {
int u;
priority_queue <elemPQ> pq;
for ( u = 0; u < vt; u++ ) {
parent[u] = -1;
realCost[u] = newCost[u];
fakeCost[u] = MULT;
vis[u] = false;
}
newCost[s] = fakeCost[s] = 0;
pq.push( { s, 0 } );
while ( !pq.empty() ) {
u = pq.top().u;
pq.pop();
if ( !vis[u] ) {
vis[u] = true;
for ( int v: edges[u] ) {
if ( fakeCost[u] + cost[u][v] + realCost[u] - realCost[v] < fakeCost[v] && flux[u][v] < cap[u][v] ) {
parent[v] = u;
fakeCost[v] = fakeCost[u] + cost[u][v] + realCost[u] - realCost[v];
newCost[v] = newCost[u] + cost[u][v];
pq.push( { v, fakeCost[v] } );
}
}
}
}
return fakeCost[t] != MULT;
}
void minCostmaxFlow() {
int newFlow, newCost, v;
bellman();
maxFlow = 0;
minCost = 0;
while ( dijkstra() ) {
newFlow = MULT;
newCost = 0;
v = t;
while ( v != s ) {
newFlow = min( newFlow, cap[parent[v]][v] - flux[parent[v]][v] );
newCost += cost[parent[v]][v];
v = parent[v];
}
maxFlow += newFlow;
minCost += newFlow * newCost;
v = t;
while ( v != s ) {
flux[parent[v]][v] += newFlow;
flux[v][parent[v]] -= newFlow;
v = parent[v];
}
}
}
};
FLOW cuplaj;
int main() {
ifstream cin( "cmcm.in" );
ofstream cout( "cmcm.out" );
int n, m, k, u, v, c;
cin >> n >> m >> k;
for ( int i = 1; i <= k; i++ ) {
cin >> u >> v >> c;
v += n;
muchie[u][v] = i;
cuplaj.add_edge( u, v, 1, c );
}
for ( u = 1; u <= n; u++ )
cuplaj.add_edge( 0, u, 1, 0 );
for ( v = n + 1; v <= n + m; v++ )
cuplaj.add_edge( v, n + m + 1, 1, 0 );
cuplaj.s = 0;
cuplaj.t = n + m + 1;
cuplaj.vt = n + m + 2;
cuplaj.minCostmaxFlow();
cout << cuplaj.maxFlow << " " << cuplaj.minCost << "\n";
for ( u = 1; u <= n; u++ ) {
for ( v = n + 1; v <= n + m; v++ ) {
if ( cuplaj.flux[u][v] )
cout << muchie[u][v] << " ";
}
}
return 0;
}