Pagini recente » Cod sursa (job #1730586) | Cod sursa (job #1874644) | Cod sursa (job #2344985) | Cod sursa (job #1035935) | Cod sursa (job #3120874)
#include <bits/stdc++.h>
using namespace std;
#ifndef LOCAL
ifstream in("cmcm.in");
ofstream out("cmcm.out");
#define cin in
#define cout out
#endif // LOCAL
struct MCMF {
struct Edge {
int from, to, flow, cap, cost;
};
static const int buffer = 7;
int n, source, sink;
vector<Edge> edges;
vector<vector<int>> edge_ids;
vector<int> potential;
vector<int> coming;
MCMF(int _n, int _source, int _sink) {
n = _n; source = _source; sink = _sink;
edge_ids.resize(n + buffer);
potential.resize(n + buffer);
coming.resize(n + buffer);
}
void add_edge(int from, int to, int cap, int cost) {
edge_ids[from].push_back(edges.size()); edges.push_back({from, to, 0, cap, cost});
edge_ids[to].push_back(edges.size()); edges.push_back({to, from, 0, 0, -cost});
}
void bellman_ford() {
vector<int> dist(n + buffer, 0);
for(int i = 0; i < n + buffer; i++) {
for(int i = 0; i < edges.size(); i += 2) {
const auto& ed = edges[i];
dist[ed.to] = min(dist[ed.to], dist[ed.from] + ed.cost);
}
}
potential = dist;
}
bool dijkstra() {
const int INF = 1e9;
vector<int> dist(n + buffer, INF);
dist[source] = 0;
priority_queue<pair<int, int>> pq;
pq.push({-dist[source], source});
while(!pq.empty()) {
auto cnt = pq.top(); pq.pop();
if(dist[cnt.second] != -cnt.first) continue;
for(auto eid : edge_ids[cnt.second]) {
const auto &ed = edges[eid];
if(ed.flow == ed.cap) continue;
if(dist[ed.to] > dist[ed.from] + (ed.cost + potential[ed.from] - potential[ed.to])) {
dist[ed.to] = dist[ed.from] + (ed.cost + potential[ed.from] - potential[ed.to]);
coming[ed.to] = eid;
pq.push({-dist[ed.to], ed.to});
}
}
}
potential = dist;
return dist[sink] != INF;
}
int64_t flow = 0, cost = 0;
void compute() {
for(auto &e : edges) e.flow = 0;
flow = 0; cost = 0;
bellman_ford();
while(dijkstra()) {
int cnt_flow = 1e9;
for(int x = sink; x != source; x = edges[coming[x]].from) {
cnt_flow = min(cnt_flow, edges[coming[x]].cap - edges[coming[x]].flow);
}
flow += cnt_flow;
for(int x = sink; x != source; x = edges[coming[x]].from) {
edges[coming[x] ^ 0].flow += cnt_flow;
edges[coming[x] ^ 1].flow -= cnt_flow;
cost += 1LL * edges[coming[x]].cost * cnt_flow;
}
}
}
int64_t max_flow() {
return flow;
}
int64_t min_cost() {
return cost;
}
vector<int> get_caps() {
vector<int> ret;
for(auto e : edges) {
if(e.flow >= 1 && e.cap >= 2) ret.push_back(e.cap - 1);
}
return ret;
}
};
int main() {
int n, m, e; cin >> n >> m >> e;
MCMF mcmf(n + m + 5, 1, 1 + n + m + 1);
for(int i = 1; i <= n; i++) {
mcmf.add_edge(1, 1 + i, 1, 0);
}
for(int i = 2; i <= e + 1; i++) {
int x, y, cost; cin >> x >> y >> cost;
mcmf.add_edge(1 + x, 1 + n + y, i, cost);
}
for(int i = 1; i <= m; i++) {
mcmf.add_edge(1 + n + i, 1 + n + m + 1, 1, 0);
}
mcmf.compute();
cout << mcmf.max_flow() << " " << mcmf.min_cost() << '\n';
for(auto e : mcmf.get_caps()) cout << e << " "; cout << '\n';
}