Pagini recente » Cod sursa (job #3163435) | Cod sursa (job #728986) | Cod sursa (job #2589713) | Cod sursa (job #2167492) | Cod sursa (job #2725492)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
const int INF = 1e9;
const int N = 605;
ifstream fin("cmcm.in");
ofstream fout("cmcm.out");
int n, m, e, maxFlow, minCost;
int cap[N][N], flow[N][N];
vector<pair<int, int>> g[N], edges;
vector<int> t, dist;
void BellmanFordCoada(int s)
{
dist.assign(n + m + 5, INF);
vector<bool> inCoada(n + m + 5);
t.assign(n + m + 5, 0);
dist[s] = 0;
queue<int> q;
q.push(s);
inCoada[s] = true;
while(!q.empty())
{
int x = q.front();
q.pop();
inCoada[x] = false;
for(auto neigh : g[x])
{
int y = neigh.first;
int cost = neigh.second;
if(flow[x][y] != cap[x][y] && dist[x] + cost < dist[y])
{
dist[y] = dist[x] + cost;
t[y] = x;
if(!inCoada[y])
{
q.push(y);
inCoada[y] = true;
}
}
}
}
}
int maxFlowMinCost(int source, int sink)
{
maxFlow = 0;
minCost = 0;
do
{
BellmanFordCoada(source);
if(dist[sink] == INF)
break;
int fmin = 1 << 30;
for(int node = sink; node != source; node = t[node])
fmin = min(fmin, cap[t[node]][node] - flow[t[node]][node]);
if(fmin == 0)
continue;
maxFlow += fmin;
minCost += dist[sink] * fmin;
for(int node = sink; node != source; node = t[node])
{
flow[t[node]][node] += fmin;
flow[node][t[node]] -= fmin;
}
} while(dist[sink] != INF);
return minCost;
}
int main()
{
cout << "Program started!\n" << endl;
fin >> n >> m >> e;
edges.reserve(e);
for(int i = 0; i < e; i++)
{
int x, y, cost;
fin >> x >> y >> cost;
y += n;
g[x].push_back({y, cost});
g[y].push_back({x, -cost});
cap[x][y] = 1;
edges.push_back({x, y});
}
// connect source with left and sink with right
for(int i = 1; i <= n; i++)
{
g[0].push_back({i, 0});
cap[0][i] = 1;
}
for(int i = n + 1; i <= n + m; i++)
{
g[i].push_back({n + m + 1, 0});
cap[i][n + m + 1] = 1;
}
maxFlowMinCost(0, n + m + 1);
fout << maxFlow << ' ' << minCost << '\n';
// 'full' edges are the ones in max coupling
for(int i = 0; i < e; i++)
{
int x = edges[i].first;
int y = edges[i].second;
if(cap[x][y] == flow[x][y])
fout << i + 1 << ' ';
}
return 0;
}