Pagini recente » Cod sursa (job #2521131) | Cod sursa (job #745761) | Cod sursa (job #1531195) | Cod sursa (job #3137652) | Cod sursa (job #1738312)
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
constexpr int maxN = 50;
constexpr int maxM = 300;
constexpr int maxTime = 128;
constexpr int setSource = 0;
constexpr int setSink = 1;
constexpr int NIL = -1;
pair <pair <int, int>, int> E[maxM];
int ini_cap[maxN];
struct MaxFlow {
struct Edge {
int v, cap;
int next;
} G[maxM * maxTime];
int head[maxN * maxTime];
MaxFlow() {
memset(head, NIL, 4 * maxN * maxTime);
}
void addEdge( const int u, const int v, const int cap ) {
static int ptr = 0;
G[ptr].v = v;
G[ptr].cap = cap;
G[ptr].next = head[u];
head[u] = ptr++;
}
void insertEdge( const int u, const int v, const int cap ) {
addEdge(u, v, cap);
addEdge(v, u, 0);
}
int dist[maxN * maxTime];
int Q[maxN * maxTime];
bool BFS() {
memset(dist, 0, 4 * maxN * maxTime);
int qHead = 0, qTail = 1;
Q[0] = setSource;
dist[setSource] = 1;
while (qHead != qTail) {
const int node = Q[qHead++];
for (int i = head[node]; i != NIL; i = G[i].next) {
const int to = G[i].v;
if (G[i].cap > 0 && !dist[to]) {
dist[to] = dist[node] + 1;
Q[qTail++] = to;
}
}
}
return dist[setSink];
}
int to[maxN * maxTime];
int DFS( const int node, const int flow ) {
if (node == setSink || !flow)
return flow;
for (; to[node] != NIL; to[node] = G[to[node]].next)
if (dist[G[to[node]].v] == dist[node] + 1) {
const int push_flow = (flow < G[to[node]].cap) ? flow : G[to[node]].cap;
const int pushed = DFS(G[to[node]].v, push_flow);
if (pushed) {
G[to[node]].cap -= pushed;
G[to[node] ^ 1].cap += pushed;
return pushed;
}
}
return 0;
}
int maxFlow() {
int flow = 0;
while (BFS()) {
memmove(to, head, 4 * maxN * maxTime);
int pushed;
do {
pushed = DFS(setSource, maxN);
flow += pushed;
} while (pushed);
}
return flow;
}
} Dinic;
int n, m;
int pushTime( int &delta ) {
for (int i = 0; i < n; i++) // raman pe aceeasi pozitie
Dinic.insertEdge(delta - n + i, delta + i, maxN);
for (int i = 0; i < m; i++) { // se muta in vecin
Dinic.insertEdge(delta - n + E[i].first.first, delta + E[i].first.second, E[i].second);
Dinic.insertEdge(delta - n + E[i].first.second, delta + E[i].first.first, E[i].second);
}
Dinic.insertEdge(delta, setSink, maxN);
delta += n;
return Dinic.maxFlow();
}
int main() {
freopen("algola.in", "r", stdin);
freopen("algola.out", "w", stdout);
int need_flow = 0;
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++) {
scanf("%d", ini_cap + i);
need_flow += ini_cap[i];
}
if (*ini_cap == need_flow) {
puts("0");
return 0;
}
for (int i = 0; i < m; i++) {
scanf("%d%d%d", &E[i].first.first, &E[i].first.second, &E[i].second);
E[i].first.first--;
E[i].first.second--;
}
int delta = 2;
for (int i = 0; i < n; i++)
Dinic.insertEdge(setSource, delta + i, ini_cap[i]);
Dinic.insertEdge(delta, setSink, maxN);
delta += n;
int theta = 1;
while (need_flow -= pushTime(delta))
theta++;
printf("%d\n", theta);
return 0;
}