Pagini recente » Cod sursa (job #1243243) | Cod sursa (job #2782154) | Cod sursa (job #2987247) | Cod sursa (job #3002162) | Cod sursa (job #3326689)
#include <bits/stdc++.h>
using namespace std;
ifstream f("cmcm.in");
ofstream g("cmcm.out");
struct date{
int node, cost;
};
struct compare{
bool operator()(date a, date b){
return a.cost > b.cost;
}
};
const int inf=1e9;
int n,m,E,x,y,c, flow[620][620], cap[620][620], cost[620][620], ogorder[620][620];
int dist[620], old_dist[620], real_dist[620], inque[620], tata[620];
vector <int> edges[620];
queue <int> q;
priority_queue <date, vector<date>, compare> pq;
void add_edge(int x, int y, int c){
edges[x].push_back(y);
edges[y].push_back(x);
cap[x][y] = 1;
cost[x][y] += c;
cost[y][x] -= c;
}
void bellmanford(int source, int sink){
for(int i=source; i<=sink; i++)
old_dist[i] = inf;
old_dist[source] = 0;
q.push(source);
while(!q.empty())
{
int x = q.front();
inque[x] = 0;
q.pop();
for(auto y:edges[x])
if(cap[x][y] != 0 and old_dist[x] + cost[x][y] < old_dist[y])
{
old_dist[y] = old_dist[x] + cost[x][y];
if(inque[y] == 0)
inque[y] = 1, q.push(y);
}
}
}
bool dijkstra(int source, int sink){
for(int i=source; i<=sink; i++)
dist[i] = inf;
dist[source] = 0;
pq.push({source, 0});
while(!pq.empty())
{
date x = pq.top();
pq.pop();
if(x.cost == dist[x.node])
{
for(auto y:edges[x.node])
{
int new_dist = old_dist[x.node] - old_dist[y] + cost[x.node][y];
if(flow[x.node][y] < cap[x.node][y] and dist[x.node] + new_dist < dist[y])
{
dist[y] = dist[x.node] + new_dist;
real_dist[y] = real_dist[x.node] + cost[x.node][y];
tata[y] = x.node;
pq.push({y, dist[y]});
}
}
}
}
return dist[sink] != inf;
}
int main()
{
f>>n>>m>>E;
for(int i=1; i<=E; i++)
{
f>>x>>y>>c;
add_edge(x, n+y, c);
ogorder[x][n+y] = i;
}
for(int i=1; i<=n; i++)
add_edge(0, i, 0);
for(int i=1; i<=m; i++)
add_edge(n+i, n+m+1, 0);
int totalflow = 0, totalcost = 0;
bellmanford(0, n+m+1);
while(dijkstra(0, n+m+1))
{
int minim = INT_MAX, sum;
for(int x=n+m+1; x>0; x=tata[x])
minim = min(minim, cap[tata[x]][x] - flow[tata[x]][x]);
totalflow += minim;
totalcost += minim*real_dist[n+m+1];
for(int x=n+m+1; x>0; x=tata[x])
{
flow[tata[x]][x] += minim;
flow[x][tata[x]] -= minim;
}
for(int i=0; i<=n+m+1; i++)
old_dist[i] = real_dist[i];
}
g<<totalflow<<' '<<totalcost<<'\n';
for(int x=1; x<=n; x++)
{
for(auto y:edges[x])
if(flow[x][y] == cap[x][y] and y!=0)
{
g<<ogorder[x][y]<<' ';
break;
}
}
return 0;
}