Pagini recente » Cod sursa (job #428895) | Cod sursa (job #1423763) | Cod sursa (job #3267368) | Cod sursa (job #2759893) | Cod sursa (job #1108426)
#include <cstring>
#include <algorithm>
#include <fstream>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
ifstream fin("critice.in");
ofstream fout("critice.out");
const int MAX_N = 1005;
const int MAX_M = 10100;
const int INF = 1 << 30;
int N, M;
vector<int> graph[MAX_N];
pair<int, int> edges[MAX_M];
bool source_path[MAX_N];
bool sink_path[MAX_N];
int cap[MAX_N][MAX_N];
int flow[MAX_N][MAX_N];
int incoming[MAX_N];
int source, sink;
vector<int> answer;
void read_input();
void solve();
void print_output();
int maxflow();
bool find_augmenting_path();
void dfs(int start, bool path[]);
int cp(int a, int b);
int main() {
read_input();
solve();
print_output();
}
void read_input() {
fin >> N >> M;
for (int i = 1, a, b, c; i <= M; ++i) {
fin >> a >> b >> c;
graph[a].push_back(b);
graph[b].push_back(a);
cap[a][b] = c;
cap[b][a] = c;
edges[i].first = a;
edges[i].second = b;
}
source = 1; sink = N;
}
void solve() {
maxflow();
dfs(source, source_path);
bool p[MAX_N];
for (int i = 2; i < N; i += 1) {
memset(p, 0, sizeof(p));
dfs(i, p);
if (p[sink]) sink_path[i] = 1;
}
for (int i = 1, a, b; i <= M; ++i) {
a = edges[i].first;
b = edges[i].second;
if ((source_path[a] && sink_path[b] && cp(a, b) == 0) ||
(sink_path[a] && source_path[b] && cp(b, a) == 0)) {
answer.push_back(i);
}
}
}
void print_output() {
fout << answer.size() << '\n';
for (auto node : answer) {
fout << node << '\n';
}
}
int maxflow() {
int result = 0;
while (find_augmenting_path()) {
for (auto i: graph[sink]) {
int new_flow = cp(i, sink);
for (int node = i; node != source; node = incoming[node]) {
new_flow = min(new_flow, cp(incoming[node], node));
}
if(new_flow == 0) continue;
flow[i][sink] += new_flow;
flow[sink][i] -= new_flow;
for (int node = i; node != source; node = incoming[node]) {
flow[incoming[node]][node] += new_flow;
flow[node][incoming[node]] -= new_flow;
}
result += new_flow;
}
memset(incoming, 0, sizeof(incoming));
}
return result;
}
bool find_augmenting_path() {
queue<int> q;
q.push(source);
source_path[source] = 1;
while (!q.empty()) {
int node = q.front();
q.pop();
if (node == sink) return true;
for (auto next: graph[node]) {
if (!incoming[next] && cp(node, next) > 0) {
incoming[next] = node;
q.push(next);
}
}
}
return false;
}
void dfs(int node, bool path[]) {
path[node] = true;
for (auto next : graph[node]) {
if (cp(node, next) > 0 && cp(next, node) > 0 && path[next] == false) {
dfs(next, path);
}
}
}
inline int cp(int a, int b) {
return cap[a][b] - flow[a][b];
}