Pagini recente » Cod sursa (job #440206) | Cod sursa (job #513562) | Cod sursa (job #434165) | Cod sursa (job #1607674) | Cod sursa (job #2112120)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
const int INF = (1 << 29);
class flow
{
public:
vector<vector<int> > cap;
vector<vector<int> > flux;
flow(int n)
{
this->n = n;
vecini.resize(n + 1);
cap.resize(n + 1, vector<int>(n + 1));
cost.resize(n + 1, vector<int>(n + 1));
dp.resize(n+1);
viz.resize(n+1);
flux.resize(n+1, vector<int>(n+1));
}
void AddEdge(int x, int y, int capacity, int cost)
{
vecini[x].push_back(y);
vecini[y].push_back(x);
cap[x][y] = capacity;
this->cost[x][y] = cost;
this->cost[y][x] = -cost;
}
long long GetMinCostMaxFlow(int source, int dest)
{
long long ret = 0;
vector<int> father(n+1);
while(BellmanFord(source, dest, flux, father))
{
int mn = INF;
for(int nod = dest; nod != source; nod = father[nod])
mn = min(mn, cap[father[nod]][nod] - flux[father[nod]][nod]);
for(int nod = dest; nod != source; nod = father[nod])
{
ret += 1LL * cost[father[nod]][nod] * mn;
flux[father[nod]][nod] += mn;
flux[nod][father[nod]] -= mn;
}
}
return ret;
}
private:
bool BellmanFord(int source, int dest, vector<vector<int> > &flux, vector<int> &father)
{
bool ret = false;
fill(dp.begin(), dp.end(), INF);
queue<int> q;
q.push(source);
dp[source] = 0;
viz[source] = true;
int nod;
while(q.empty() == false)
{
nod = q.front();
q.pop();
if(nod == dest)
ret = true;
viz[nod] = false;
for(auto v:vecini[nod])
{
if(cap[nod][v] == flux[nod][v])
continue;
if(dp[nod] + cost[nod][v] < dp[v])
{
dp[v] = dp[nod] + cost[nod][v];
father[v] = nod;
if(viz[v] == false)
{
q.push(v);
viz[v] = true;
}
}
}
}
return ret;
}
int n;
vector<vector<int> > vecini;
vector<vector<int> > cost;
vector<int> dp;
vector<bool> viz;
};
int main()
{
ifstream in("cmcm.in");
int n, m, e, p, q, c;
in >> n >> m >> e;
vector<vector<int> > edgeId(n+1, vector<int>(m+1));
int source = n + m + 1, dest = n + m + 2;
flow gr(n + m + 2);
for(int i = 1; i <= e; ++i)
{
in >> p >> q >> c;
gr.AddEdge(p, n + q, 1, c);
edgeId[p][q] = i;
}
in.close();
for(int i = 1; i <= n; ++i)
gr.AddEdge(source, i, 1, 0);
for(int i = 1; i <= m; ++i)
gr.AddEdge(n + i, dest, 1, 0);
ofstream out("cmcm.out");
int cost = gr.GetMinCostMaxFlow(source, dest);
vector<int> rasp;
for(int i = 1; i <= n; ++i)
for(int j = n + 1; j <= n + m; ++j)
if(gr.flux[i][j] && gr.cap[i][j])
rasp.push_back(edgeId[i][j-n]);
out << rasp.size() << " " << cost << "\n";
for(auto x:rasp)
out << x << " ";
out.close();
return 0;
}