Pagini recente » Cod sursa (job #50037) | Cod sursa (job #846265) | Cod sursa (job #161674) | Cod sursa (job #731946) | Cod sursa (job #3333105)
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int MAXN = 705;
ifstream fin("cmcm.in");
ofstream fout("cmcm.out");
struct Edge {
int to;
int flow;
int cap;
int cost;
int rev; // indicele muchiei inverse a lui 'to'
int id; // indice original
};
vector<Edge> adj[MAXN];
int dist[MAXN];
int parent_node[MAXN];
int parent_edge_idx[MAXN];
bool inQueue[MAXN];
int N, M, E, S, D;
void add_edge(int u, int v, int cap, int cost, int id = -1) {
Edge forward = {v, 0, cap, cost, (int)adj[v].size(), id};
Edge backward = {u, 0, 0, -cost, (int)adj[u].size(), -1};
adj[u].push_back(forward);
adj[v].push_back(backward);
}
bool spfa() {
for(int i = 0; i <= D; ++i) {
dist[i] = INF;
inQueue[i] = false;
parent_node[i] = -1;
}
dist[S] = 0;
queue<int> q;
q.push(S);
inQueue[S] = true;
while(!q.empty()) {
int u = q.front();
q.pop();
inQueue[u] = false;
for(int i = 0; i < adj[u].size(); ++i) {
Edge &e = adj[u][i];
if(e.cap - e.flow > 0 && dist[e.to] > dist[u] + e.cost) {
dist[e.to] = dist[u] + e.cost;
parent_node[e.to] = u;
parent_edge_idx[e.to] = i;
if(!inQueue[e.to]) {
q.push(e.to);
inQueue[e.to] = true;
}
}
}
}
return dist[D] != INF;
}
int main() {
fin >> N >> M >> E;
S = 0;
D = N + M + 1;
for(int i = 1; i <= E; ++i) {
int u, v, cost;
fin >> u >> v >> cost;
add_edge(u, N + v, 1, cost, i);
}
fin.close();
for(int i = 1; i <= N; ++i) {
add_edge(S, i, 1, 0);
}
for(int i = 1; i <= M; ++i) {
add_edge(N + i, D, 1, 0);
}
int max_flow = 0;
int min_cost = 0;
while(spfa()) {
int flow = INF;
int curr = D;
while(curr != S) {
int prev = parent_node[curr];
int idx = parent_edge_idx[curr];
flow = min(flow, adj[prev][idx].cap - adj[prev][idx].flow);
curr = prev;
}
curr = D;
while(curr != S) {
int prev = parent_node[curr];
int idx = parent_edge_idx[curr];
adj[prev][idx].flow += flow;
int rev_idx = adj[prev][idx].rev;
adj[curr][rev_idx].flow -= flow;
min_cost += flow * adj[prev][idx].cost;
curr = prev;
}
max_flow += flow;
}
fout << max_flow << " " << min_cost << "\n";
// L->R care au flux 1
bool first = true;
for(int u = 1; u <= N; ++u) {
for(auto &e : adj[u]) {
if(e.to > N && e.to <= N + M && e.flow == 1 && e.id != -1) {
fout << e.id << " ";
first = false;
}
}
}
fout << "\n";
return 0;
}