Pagini recente » Cod sursa (job #515580) | Cod sursa (job #2611076) | Cod sursa (job #2287133) | Solutii preONI 2008, Runda 1 | Cod sursa (job #2237863)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream in ("critice.in");
ofstream out ("critice.out");
int const NMAX = 10000;
int const MMAX = 100000;
int const inf = 1000000000;
#define MIN(a , b) ((a < b) ? a : b)
#define MAX(a , b) ((a < b) ? b : a)
struct Edge{
int to;
int rev;
int cap;
int flow;
int index;
};
vector < Edge > g[5 + NMAX];
void addEdge(int from , int to , int cap , int index){
g[from].push_back({to , g[to].size() , cap , 0, index });
g[to].push_back({from , g[from].size() - 1 , cap , 0 , index} );
}
int level[5 + NMAX];
int n;
bool bfs(){
queue< int > q;
for(int i = 1 ; i <= n ;i++)
level[i] = 0;
level[1] = 1;
q.push(1);
while(0 < q.size()){
int node = q.front();
q.pop();
for(int h = 0 ; h < g[node].size() ;h++){
Edge e = g[node][h];
if(e.flow < e.cap && level[e.to] == 0){
level[e.to] = level[node] + 1;
q.push(e.to);
}
}
}
return 0 < level[n];
}
int rem[5 + NMAX];
int dfs(int node , int deltaflow){
if(node == n)
return deltaflow;
for(int &h = rem[node] ; h < g[node].size() ;h++){
Edge &e = g[node][h];
if(level[node] + 1 == level[e.to] && e.flow < e.cap){
int delta = dfs(e.to ,MIN(deltaflow ,e.cap - e.flow));
if(0 < delta){
e.flow += delta;
g[e.to][e.rev].flow -= delta;
return delta;
}
}
}
return 0;
}
int maxflow(){
int flowsum = 0;
while(bfs()){
for(int i = 1 ; i <= n ;i++)
rem[i] = 0;
int deltaflow = 0;
bool ok = 0;
do{
deltaflow = dfs(1 , inf);
flowsum += deltaflow;
} while(0 < deltaflow);
}
return flowsum;
}
int marker[5 + NMAX];
void mark(int node ,int val ){
queue < int > q;
q.push(node);
int seen[5 + NMAX] = {0};
while(0 < q.size()){
int node = q.front();
marker[node] |= val;
q.pop();
for(int h = 0 ; h < g[node].size() ;h++){
Edge &e = g[node][h];
if(e.flow < e.cap && g[e.to][e.rev].flow < e.cap && seen[e.to] == 0){
seen[e.to] = 1;
q.push(e.to);
}
}
}
}
vector<pair<int , int >> edges;
int main()
{
int m;
in >> n >> m;
edges.push_back({0 , 0});
for(int i = 1 ; i <= m ;i++){
int from , to , cap;
in >> from >> to >> cap;
addEdge(from , to , cap , i);
edges.push_back({from , to});
}
maxflow();
mark(1 , 1);
mark(n , 2);
int result = 0;
for(int i = 1 ; i <= m;i++)
if((marker[edges[i].first] == 1 && marker[edges[i].second] == 2) || (marker[edges[i].first] == 2 && marker[edges[i].second] == 1))
result++;
out << result << '\n';
for(int i = 1 ; i <= m ;i++){
if((marker[edges[i].first] == 1 && marker[edges[i].second] == 2) || (marker[edges[i].first] == 2 && marker[edges[i].second] == 1))
out << i << '\n';
}
return 0;
}