Pagini recente » Cod sursa (job #3136341) | Cod sursa (job #1411264) | Cod sursa (job #1593746) | Cod sursa (job #1973079) | Cod sursa (job #2820743)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#include <cmath>
#define inf 1000000009
using namespace std;
ifstream fin("critice.in");
ofstream fout("critice.out");
//listele de adiacenta
vector<vector<int>> la;
//matricele de flux si capacitate
vector<vector<int>> flux;
vector<vector<int>> capacitate;
int n,m;
//vectorul de muchii care ajuta la retinerea indicelui fiecarei muchii
vector<pair<int,int>> muchii;
//vectorii tati si vizitat folositi in parcurgerea bfs
vector<int> tati;
vector<int> vizitat;
bool BfsMaxFlow(int S, int D)
{
//complexitatea algoritmului este O(n)
tati[D] = 0;
//golesc vectorul vizitat la fiecare parcurgere
vizitat.clear();
//redimensionam vectorul vizitat si il initializam
vizitat.resize(n+1, 0);
//coada folosita in parcurgerea Bfs
queue<int> q;
//punem in coada nodul de start
q.push(S);
tati[S] = 0;
vizitat[S] = true;
//cat timp coada nu este goala(mai am elemente de procesat) si nu s-a ajunj inca in destinatie
//parcurg Bfs
while(!q.empty() && tati[D] == 0)
{
//luam urmatorul element din coada
int x = q.front();
q.pop();
//ii parcurgem lista de adiacenta
for(int i=0; i<la[x].size(); ++i)
{
int y = la[x][i];
//daca nodul adiacent curent nu a fost vizitat si arcul de la x la y este unul nesaturat
if(vizitat[y] == true || capacitate[x][y] == flux[x][y])
continue;
tati[y] = x;
vizitat[y] = true;
q.push(y);
}
}
if(tati[D]!=0)
return true;
else
return false;
}
int MaxFlow(int S, int D)
{
//complexitatea algoritmului este O(n*(m^2))
//golesc vectorul tati
tati.clear();
//redimensionam vectorul tati si il initializam
tati.resize(n+1, 0);
int rez = 0;
//dimensionam si initializam matricea flux
flux.resize(n+1, vector<int>(n+1, 0));
//cat timp gasesc un drum de ameliorare de la sursa la destinatie
while(BfsMaxFlow(S, D))
{
for(int i=0; i<la[D].size(); ++i)
{
int y = la[D][i];
if (flux[y][D] == capacitate[y][D] || !vizitat[y])
continue;
tati[D] = y;
int a = inf;
//parcurg drumul de la D la S pentru a determina cu cat se poate modifica fluxul pe acel drum
for (int i = D; i != S; i = tati[i])
a = min(a, capacitate[tati[i]][i] - flux[tati[i]][i]);
if (a == 0)
continue;
//parcurg din nou drumul pentru a face actualizarea
for (int i = D; i != S; i = tati[i])
{
flux[tati[i]][i] += a;
flux[i][tati[i]] += a;
}
rez += a;
}
}
return rez;
}
void Dfs1(int nod, vector<int> &vizitat)
{
vizitat[nod] = 1;
for(int i = 0; i < la[nod].size(); ++i)
{
int y = la[nod][i];
if(vizitat[y] == 0 && capacitate[nod][y] > flux[nod][y]) //doar muchiile nesaturate
{
Dfs1(y, vizitat);
}
}
}
//void Dfs2(int nod, vector<int> &vizitat)
//{
// vizitat[nod] = 1;
//
// for(int i = 0; i < la[nod].size(); ++i)
// {
// int y = la[nod][i];
// if(vizitat[y] == 0 && capacitate[y][nod] > flux[y][nod]) //doar muchiile nesaturate
// {
// Dfs2(y, vizitat);
// }
// }
//}
int main()
{
fin >> n >> m;
//dimensionam matricea capacitate
capacitate.resize(n+1, vector<int>(n+1, 0));
//dimensionam vectorul muchii
muchii.resize(m+1);
//dimensionam listele de adiacenta
la.resize(n+1);
for(int i = 0; i < m; ++i)
{
int x, y, c;
fin >> x >> y >> c;
//completam listele de adiacenta
la[x].push_back(y);
la[y].push_back(x);
//completam vectorul de muchii
muchii[i].first = x;
muchii[i].second = y;
//completam matricea de capacitati
capacitate[x][y] = c;
capacitate[y][x] = c;
}
//impingem fluxul maxim posibil prin retea
MaxFlow(1, n);
vector<int> vizitat1(n+1);
//vector<int> vizitat2(n+1);
vector<int> rezultat;
//aflam muchiile pentru care daca marim capacitatile obtinem un flux maxim mai mare pentru reteaua data
Dfs1(1, vizitat1);
//Dfs2(n, vizitat2);
for(int i = 0; i < m; ++i)
{
int x = muchii[i].first;
int y = muchii[i].second;
if((vizitat1[x] && !vizitat1[y]) || (vizitat1[y] && !vizitat1[x]))
rezultat.push_back(i+1);
// if((vizitat1[x] && vizitat2[y]) || (vizitat1[y] && vizitat2[x]))
// rezultat.push_back(i+1);
}
int nr = rezultat.size();
fout << nr << "\n";
for(int i = 0; i < nr; ++i)
fout << rezultat[i] << "\n";
return 0;
}