Pagini recente » Cod sursa (job #3306660) | Cod sursa (job #3341994) | Cod sursa (job #3342247) | Cod sursa (job #1468783) | Cod sursa (job #3328163)
#include <fstream>
#include <bitset>
#include <vector>
#include <queue>
using namespace std;
const int NMAX = 1000;
const int MMAX = 10000;
ifstream cin("critice.in");
ofstream cout("critice.out");
struct nod_flux{
int nod;
int cap;
int flux;
int pereche;
};
vector <vector <nod_flux>> v;
int n;
struct muchii{
int nod1, nod2, cap;
}edge[MMAX + 2];
void add(muchii x) { ///avem in ambele directii
if(x.nod1 > x.nod2)
swap(x.nod1, x.nod2);
v[x.nod1].push_back({x.nod2, x.cap, 0, -1});
v[x.nod2].push_back({x.nod1, x.cap, 0, -1});
v[x.nod1].back().pereche = v[x.nod2].size() - 1;
v[x.nod2].back().pereche = v[x.nod1].size() - 1;
if(x.nod1 == 1) ///NU ne ducem inapoi la 1
v[x.nod2].back().cap = 0;
if(x.nod2 == n) ///NU iesim din destinatie
v[x.nod2].back().cap = 0;
}
bitset <NMAX + 2> viz;
pair <int, int> tata[NMAX + 2]; ///tata, muchie
bool bfs() {
viz = 0;
viz[1] = 1; ///sursa!!
queue <int> q;
q.push(1);
while(!q.empty()) {
int now = q.front();
q.pop();
for(int i = 0; i < v[now].size(); i++) {
nod_flux x = v[now][i];
if(!viz[x.nod] && x.flux < x.cap) {
viz[x.nod] = 1;
tata[x.nod] = {now, i};
q.push(x.nod);
}
}
}
return viz[n]; ///destinatia!!!
}
int recons(int start, int minn) {
while(tata[start].first) {
minn = min(minn, v[tata[start].first][tata[start].second].cap - v[tata[start].first][tata[start].second].flux);
start = tata[start].first;
if(minn <= 0)
return minn;
}
return minn;
}
void change(int a, int b, int muchie, int val) {
v[a][muchie].flux += val;
v[b][v[a][muchie].pereche].flux -= val;
}
void update(int start, int val) {
while(tata[start].first) {
change(tata[start].first, start, tata[start].second, val);
start = tata[start].first;
}
}
bitset <NMAX + 2> b[2];
void bfsAccesibil(int start, bool tip) {
queue <int> q;
b[tip][start] = 1;
q.push(start);
while(!q.empty()) {
int now = q.front();
q.pop();
for(auto x : v[now]) {
if(b[tip][x.nod])
continue;
if(!tip) { ///pe normal
if(x.flux < x.cap) {
b[0][x.nod] = 1;
q.push(x.nod);
}
}
else {
if(v[x.nod][x.pereche].flux < v[x.nod][x.pereche].cap) {
b[1][x.nod] = 1;
q.push(x.nod);
}
}
}
}
}
int main() {
int m;
cin >> n >> m;
v.resize(n + 1);
for(int i = 1; i <= m; i++) {
cin >> edge[i].nod1 >> edge[i].nod2 >> edge[i].cap;
add(edge[i]);
}
///facem fluxul
while(bfs()) {
for(int i = 0; i < v[n].size(); i++) {
nod_flux x = v[n][i];
if(viz[x.nod] && v[x.nod][x.pereche].flux < v[x.nod][x.pereche].cap) {
int add = recons(x.nod, v[x.nod][x.pereche].cap - v[x.nod][x.pereche].flux);
if(add > 0) {
change(x.nod, n, x.pereche, add);
update(x.nod, add);
}
}
}
}
/*for(int i = 1; i <= n; i++) {
cout << "Nodul " << i << '\n';
for(auto x : v[i])
cout << x.nod << " " << x.flux << "/" << x.cap << " " << x.pereche << "\n";
}*/
bfsAccesibil(1, 0);
bfsAccesibil(n, 1);
/*for(int j = 0; j <= 1; j++) {
for(int i = 1; i <= n; i++) {
if(b[j][i])
cout << i << " ";
}
cout << '\n';
}*/
int cnt = 0;
for(int i = 1; i <= m; i++) {
if((b[0][edge[i].nod1] && b[1][edge[i].nod2]) || (b[1][edge[i].nod1] && b[0][edge[i].nod2]))
cnt++;
}
cout << cnt << '\n';
for(int i = 1; i <= m; i++) {
if((b[0][edge[i].nod1] && b[1][edge[i].nod2]) || (b[1][edge[i].nod1] && b[0][edge[i].nod2]))
cout << i << '\n';
}
return 0;
}