Pagini recente » Cod sursa (job #1615835) | Cod sursa (job #782695) | Cod sursa (job #984418) | Cod sursa (job #1426636) | Cod sursa (job #864899)
Cod sursa(job #864899)
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <deque>
using namespace std;
ifstream f("critice.in");
ofstream g("critice.out");
#define nmax 1005
#define ll long long
#define inf (1<<30)
int n, m, t[nmax];
bool viz[nmax], alb[nmax], negru[nmax];
queue< int > q;
vector< int> gf[nmax],rez;
int capac[nmax][nmax], flux[nmax][nmax];
pair<int,int> M[nmax];
void citeste(){
f >> n >> m;
int x, y, z;
for(int i=1; i<=m; ++i){
f >> x >> y >> z;
capac[x][y] = z;
capac[y][x] = z;
gf[x].push_back(y);
gf[y].push_back(x);
M[i] = make_pair(x, y);
}
}
inline bool bfs(){
for(int i=1; i<=n; ++i) viz[i] = 0, t[i] = 0;
for(; q.size(); q.pop());
q.push(1); viz[1] = 1;
for(; q.size(); ){
int nod = q.front(); q.pop();
for(int i=0; i<gf[nod].size(); ++i){
int vc = gf[nod][i];
if (viz[vc] == 0 && capac[nod][vc] > flux[nod][vc]){
t[vc] = nod;
viz[vc] = 1; q.push(vc);
if (vc == n) return 1;
}
}
}
return 0;
}
void bfsMarc(int nod, bool v[], int cod){// daca cod = 0 sunt din sursa spre destinatie
for(int i=0; i<=n; ++i) v[i] = 0;
for(; q.size(); q.pop());
v[nod] = 1; q.push(nod);
for(; q.size(); ){
int nod = q.front(); q.pop();
for(int i=0; i<gf[nod].size(); ++i){
int vc = gf[nod][i];
if (v[vc] == 1) continue;
if (cod == 0){// am nod - > vc;
if (capac[nod][vc] > flux[nod][vc]) v[vc] = 1, q.push(vc);
}else {// acum pornesc din destinatie dar pompez flux pe vc -> nod
if (capac[vc][nod] > flux[vc][nod]) v[vc] = 1, q.push(vc);
}
}
}
}
void rezolva(){
// ideea e asa : bag un flux maxim iar apoi vreau sa vad acele muchii care sunt saturate si care sunt accesibile din sursa si din destinatie
// evident sa ajung la muchia asta doar pe muchii pe care mai pot baga flux
for(; bfs(); ){
int Min = inf;// aleg fluxul pe drumul curent
for(int i=n; t[i]!=0; i=t[i]){
//am muchia t[i] -> i
Min = min( Min, capac[ t[i] ][i] - flux[ t[i] ][i]);
}
//bag fluxul pe drumul curent
for(int i=n; t[i]!=0; i=t[i]){
// m-am dus pe muchia t[i]->i
flux[ t[i] ][i] += Min;// bag flux
flux[ i ][ t[i] ] -= Min;// il intorc;
}
}
// acum marchez nodurile accesibile din destinatie si din sursa mergand doar pe muchii nesaturate
bfsMarc(1, alb, 0); bfsMarc(1, negru, 1);
// acum vad muchiile saturate care au capatele accesibile din sursa si din destinatie
for(int i=1; i<=m; ++i){
int X = M[i].first; int Y = M[i].second;
if ( ( (alb[X] == 1 && negru[Y] == 1 && capac[X][Y] == flux[X][Y]) || (alb[Y] == 1 && negru[X] == 1 && flux[Y][X] == capac[Y][X]) ) ){
rez.push_back(i);
}
}
sort(rez.begin(), rez.end());
g << rez.size() <<"\n";
for(int i=0; i<rez.size(); ++i){
g << rez[i] << "\n";
}
}
int main(){
citeste();
rezolva();
f.close();
g.close();
return 0;
}