Pagini recente » Cod sursa (job #991029) | Cod sursa (job #1007550) | Cod sursa (job #2597396) | Cod sursa (job #1775668) | Cod sursa (job #2698090)
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
ifstream fin("cmcm.in");
ofstream fout("cmcm.out");
const int NMAX = 700;
const int source = 1;
int N, M, E;
vector<pair<int,int>> G[NMAX];
int sink, edge[NMAX][NMAX], capacity[NMAX][NMAX], flow[NMAX][NMAX];
int ans, cnt;
void read() {
fin >> N >> M >> E;
for(int i = 1; i <= E; ++i) {
int u, v, w;
fin >> u >> v >> w;
++u, v += N + 1;
G[u].emplace_back(v, w);
G[v].emplace_back(u, -w);
edge[u][v] = i;
capacity[u][v] = 1;
}
}
void build() {
sink = N + M + 2;
for(int i = source + 1; i < N + 2; ++i) {
G[1].emplace_back(i, 0);
G[i].emplace_back(1, 0);
capacity[1][i] = 1;
}
for(int i = N + 2; i < sink; ++i) {
G[i].emplace_back(sink, 0);
G[sink].emplace_back(i, 0);
capacity[i][sink] = 1;
}
}
void min_self(int &a, int b) {
a = min(a, b);
}
int BellmanFord() {
int dp[NMAX], father[NMAX];
bool used[NMAX];
memset(dp, 0x3f, sizeof(dp));
memset(used, false, sizeof(used));
fill(father, father + NMAX, -1);
dp[source] = 0;
used[source] = true;
queue<int> Q;
Q.emplace(source);
while(!Q.empty()) {
int curr = Q.front();
Q.pop();
used[curr] = false;
for(const pair<int,int> &next : G[curr])
if(capacity[curr][next.first] > flow[curr][next.first]
&& dp[next.first] > dp[curr] + next.second) {
dp[next.first] = dp[curr] + next.second;
father[next.first] = curr;
if(!used[next.first]) {
Q.emplace(next.first);
used[next.first] = true;
}
}
}
if(dp[sink] < INF) {
int flux = INF;
for(int node = sink; node != source; node = father[node])
min_self(flux, capacity[father[node]][node] - flow[father[node]][node]);
for(int node = sink; node != source; node = father[node]) {
flow[father[node]][node] += flux;
flow[node][father[node]] -= flux;
}
return flux * dp[sink];
}
return 0;
}
void max_flow() {
int improve = 1;
while(improve != 0) {
improve = BellmanFord();
ans += improve;
}
}
void print() {
for(int i = source + 1; i < N + 2; ++i)
for(int j = N + 2; j < sink; ++j)
if(flow[i][j] > 0) {
++cnt;
break;
}
fout << cnt << ' ' << ans << '\n';
for(int i = source + 1; i < N + 2; ++i)
for(int j = N + 2; j < sink; ++j)
if(flow[i][j] > 0) {
fout << edge[i][j] << ' ';
break;
}
}
int main() {
read();
build();
max_flow();
print();
}