Pagini recente » Cod sursa (job #3262664) | Cod sursa (job #1801113) | Cod sursa (job #2377994) | Cod sursa (job #627754) | Cod sursa (job #2244737)
#include <bits/stdc++.h>
#define MaxN 1005
#define MaxM 10005
#define inf (int)(1e9)
#define mp std::make_pair
std::ifstream InFile("critice.in");
std::ofstream OutFile("critice.out");
struct GraphStruct {
int N, M;
struct NodeStruct {
struct ADCStruct {
int Node, // Unde ajunge muchia
EdgeIndex; // Index-ul pentru muchie, dupa cum a fost citita
ADCStruct (int Node, int EdgeIndex) {
this->Node = Node; this->EdgeIndex = EdgeIndex;
}
};
std::list <ADCStruct> ADC;
} Node[MaxN];
std::pair <int, int> ReadEdge[MaxM];
int EdgeIndex[MaxN][MaxN], Capacity[MaxM],
Flow[MaxM]; // Flux-ul pe care il avem pentru muchia cu index i
void AddEdge(int x, int y, int res, int i) { // Muchiile impare sunt muchiile pozitive x->y, muchiile pare cele negative x<-y
Node[x].ADC.push_back(NodeStruct::ADCStruct(y, 2*i+1)); // Ca sa transform muchia i dupa cum am citit-o la inceput fac (i+1)/2
Node[y].ADC.push_back(NodeStruct::ADCStruct(x, 2*i+2));
Capacity[2*i+1] = Capacity[2*i+2] = res;
Flow[2*i+1] = Flow[2*i+2] = 0;
EdgeIndex[x][y] = 2*i+1;
EdgeIndex[y][x] = 2*i+2;
ReadEdge[i+1] = mp(x, y);
}
int Visit[MaxN];
void DFS(int Start, int Value) {
Visit[Start] = Value;
for (auto ADC:Node[Start].ADC)
if (!Visit[ADC.Node])
if (Flow[ADC.EdgeIndex] != abs(Capacity[ADC.EdgeIndex]))
DFS (ADC.Node, Value);
}
int Previous[MaxN];
bool BFSAugmentingPath() {
for (int i=0; i<N; i++)
Previous[i+1] = 0;
std::queue <int> BFSQueue;
BFSQueue.push(1);
Previous[1] = -1;
int Front;
while(!BFSQueue.empty()) {
Front = BFSQueue.front();
BFSQueue.pop();
if(Front == N) continue;
for (auto ADC:Node[Front].ADC) {
if (Previous[ADC.Node]!=0 || Flow[ADC.EdgeIndex] == Capacity[ADC.EdgeIndex]) continue;
BFSQueue.push(ADC.Node);
Previous[ADC.Node] = Front;
}
} return (Previous[N] > 0);
}
void EdmondKarp() {
while(BFSAugmentingPath()) {
for (auto ADC:Node[N].ADC) { // Luam acum toate path-urile gasite
if (Flow[ADC.EdgeIndex] == Capacity[ADC.EdgeIndex] || !Previous[ADC.Node]) continue;
int MinFlow = inf;
Previous[N] = ADC.Node;
int p; p = N;
while (p!=1)
MinFlow = std::min (MinFlow, Capacity[EdgeIndex[Previous[p]][p]] - Flow[EdgeIndex[Previous[p]][p]]),
p = Previous[p];
if (MinFlow == 0) continue;
p = N;
while (p!=1)
Flow[EdgeIndex[Previous[p]][p]] += MinFlow,
Flow[EdgeIndex[p][Previous[p]]] -= MinFlow,
p = Previous[p];
}
}
}
} Graph;
std::vector <int> CriticalEdges;
void Citire() {
InFile >> Graph.N >> Graph.M;
for (int i=0, x, y, res; i<Graph.M; i++)
InFile >> x >> y >> res,
Graph.AddEdge(x, y, res, i);
}
void Rezolvare() {
Graph.EdmondKarp();
Graph.DFS(1, 1);
Graph.DFS(Graph.N, 2);
for (int i=0; i<Graph.M; i++)
if (Graph.Visit[Graph.ReadEdge[i+1].first] && Graph.Visit[Graph.ReadEdge[i+1].second] && Graph.Visit[Graph.ReadEdge[i+1].first] != Graph.Visit[Graph.ReadEdge[i+1].second])
CriticalEdges.push_back(i+1);
OutFile << CriticalEdges.size() << '\n' ;
for (int i=0; i<CriticalEdges.size(); i++)
OutFile << CriticalEdges[i] << '\n' ;
}
int main()
{
Citire();
Rezolvare();
return 0;
}