Pagini recente » Cod sursa (job #1030451) | Cod sursa (job #2925725) | Cod sursa (job #2904847) | Cod sursa (job #2754148) | Cod sursa (job #3148084)
#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;
void 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;
}