Pagini recente » Cod sursa (job #3204912) | Cod sursa (job #2436038) | Cod sursa (job #2278748) | Cod sursa (job #2808645) | Cod sursa (job #2949631)
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
const int nmax = 602;
const int oo = 1e9;
ifstream fin ( "cmcm.in" );
ofstream fout ( "cmcm.out" );
struct edge {
int a; int b;
int flux;
int cost;
};
vector < edge > edges;
vector < int > adj[nmax + 1];
bool inQ[nmax + 1];
int dist[nmax + 1];
int real_dist[nmax + 1];
int fake_dist[nmax + 1];
bool vis[nmax + 1];
int p[nmax + 1];
int p_edge[nmax + 1];
int NODES, source, sink;
void add_edge ( const int &x, const int &y, const int &capacitate, const int &cost ) {
int sz = edges.size ();
edges.push_back ( { x, y, capacitate, cost } );
adj[x].push_back ( sz );
edges.push_back ( { y, x, 0, -cost } );
adj[y].push_back ( sz + 1 );
}
int bellman ( int start = source ) {
for ( int i = 0; i < NODES; i++ )
inQ[i] = false, dist[i] = oo;
queue < int > q;
q.push ( start );
dist[start] = 0;
while ( ! q.empty () ) {
int node = q.front ();
q.pop ();
inQ[node] = false;
for ( int x: adj[node] ) {
edge e = edges[x];
int v = e.b;
if ( e.flux > 0 && dist[v] > dist[node] + e.cost ) {
dist[v] = dist[node] + e.cost;
if ( inQ[v] == false ) {
inQ[v] = true;
q.push ( v );
}
}
}
}
return ( dist[sink] != oo );
}
int dijkstra ( int start = source ) {
priority_queue < pair < int, int > > pq;
for ( int i = 0; i < NODES; i++ ) {
vis[i] = 0;
p[i] = -1;
p_edge[i] = -1;
real_dist[i] = dist[i];
fake_dist[i] = oo;
}
p[start] = -1;
dist[start] = fake_dist[start] = 0;
pq.push ( { 0, start } );
while ( ! pq.empty () ) {
int node = pq.top ().second;
pq.pop ();
if ( vis[node] == 0 ) {
vis[node] = 1;
for ( int x: adj[node] ) {
edge e = edges[x];
int v = e.b;
if ( e.flux > 0 && fake_dist[v] > fake_dist[node] + real_dist[node] + e.cost - real_dist[v] ) {
fake_dist[v] = fake_dist[node] + real_dist[node] + e.cost - real_dist[v];
dist[v] = dist[node] + e.cost;
p[v] = node;
p_edge[v] = x;
pq.push ( { -fake_dist[v], v } );
}
}
}
}
return fake_dist[sink] != oo;
}
int min_cost_flow ( int source, int sink ) {
int maxFlow = 0, minCost = 0;
bellman ( source );
while ( dijkstra ( source ) ) {
int node = sink, flow = oo, Cost = 0;
while ( node != source ) {
flow = min ( flow, edges[p_edge[node]].flux );
Cost += edges[p_edge[node]].cost;
node = p[node];
}
node = sink;
while ( node != source ) {
edges[p_edge[node]].flux -= flow;
edges[p_edge[node] ^ 1].flux += flow;
node = p[node];
}
maxFlow += flow;
minCost += Cost * flow;
}
return minCost;
}
int main () {
int n1, n2, m, v, w, x;
fin >> n1 >> n2 >> m;
NODES = n1 + n2 + 2;
source = 0; sink = n1 + n2 + 1;
for ( int i = 0; i < m; i++ ) {
fin >> v >> w >> x;
add_edge ( v, n1 + w, 1, x );
}
for ( int i = 1; i <= n1; i++ )
add_edge ( source, i, 1, 0 );
for ( int i = 1; i <= n2; i++ )
add_edge ( n1 + i, sink, 1, 0 );
int cnt = 0, cost;
cost = min_cost_flow ( source, sink );
for ( int i = 0; i < m; i++ )
if ( edges[2 * i].flux == 0 )
cnt++;
fout << cnt << ' ' << cost << '\n';
for ( int i = 0; i < m; i++ )
if ( edges[2 * i].flux == 0 )
fout << i + 1 << ' ';
return 0;
}