Cod sursa(job #1555912)

Utilizator vladrochianVlad Rochian vladrochian Data 23 decembrie 2015 18:33:11
Problema Algola Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.26 kb
#include <cstring>
#include <fstream>
#include <queue>
#include <vector>

using namespace std;

const int N_MAX = 50;
const int M_MAX = 300;
const int NODES = 5001;
const int INF = 1e9;

ifstream fin("algola.in");
ofstream fout("algola.out");

int N, M, T;
vector<pair<int, int>> al[N_MAX + 5];

vector<int> G[NODES + 5];
bool use[NODES + 5];
int padre[NODES + 5];

int max_flow, total;
int flow[NODES + 5][NODES + 5];
int capacity[NODES + 5][NODES + 5];

inline void AddEdge(int x, int y, int c) {
   G[x].push_back(y);
   G[y].push_back(x);
   capacity[x][y] = c;
}

bool Bfs() {
   memset(use, 0, sizeof use);
   queue<int> q;
   q.push(0);
   use[0] = true;
   while (!q.empty()) {
      int node = q.front();
      q.pop();
      if (node == NODES)
         continue;
      for (int son : G[node])
         if (!use[son] && flow[node][son] < capacity[node][son]) {
            padre[son] = node;
            q.push(son);
            use[son] = true;
         }
   }
   return use[NODES];
}

void GetFlow() {
   while (Bfs())
      for (int node : G[NODES])
         if (use[node] && flow[node][NODES] < capacity[node][NODES]) {
            padre[NODES] = node;
            int crt_flow = INF;
            for (int i = NODES; i != 0; i = padre[i])
               crt_flow = min(crt_flow, capacity[padre[i]][i] - flow[padre[i]][i]);
            for (int i = NODES; i != 0; i = padre[i]) {
               flow[padre[i]][i] += crt_flow;
               flow[i][padre[i]] -= crt_flow;
            }
            max_flow += crt_flow;
         }
}

int main() {
   fin >> N >> M;
   for (int i = 1; i <= N; ++i) {
      int x;
      fin >> x;
      total += x;
      AddEdge(0, i, x);
   }
   for (int i = 0; i < M; ++i) {
      int x, y, c;
      fin >> x >> y >> c;
      al[x].emplace_back(y, c);
      al[y].emplace_back(x, c);
   }

   AddEdge(1, NODES, INF);
   GetFlow();
   while (max_flow < total) {
      ++T;
      for (int i = 1; i <= N; ++i) {
         AddEdge((T - 1) * N + i, T * N + i, INF);
         for (auto edge : al[i])
            AddEdge((T - 1) * N + i, T * N + edge.first, edge.second);
      }
      AddEdge(T * N + 1, NODES, INF);
      GetFlow();
   }

   fout << T << "\n";
   return 0;
}