Cod sursa(job #1964686)

Utilizator tudi98Cozma Tudor tudi98 Data 13 aprilie 2017 16:58:08
Problema Algola Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.01 kb
#include <bits/stdc++.h>
using namespace std;

#define REP(i,a) for (int i = 0; i < a; i++)
#define FOR(i,a,b) for (int i = a; i <= b; i++)
#define ROF(i,a,b) for (int i = a; i >= b; i--)
#define FOREACH(it,x) for (__typeof((x).begin()) it = (x).begin(); it != (x).end(); it++)
#define all(x) (x).begin(),(x).end()
#define UNIQUE(x) sort(all(x)),(x).erase(unique(all(x)),(x).end())
#define ll long long
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define SZ(x) ((int)(x).size())

const int inf = 1<<29;
const int Tmax = 100;
const int Nmax = 53;
const int Source = 51;
const int Sink = 52;

int n,m,MEMBERS = 0;
int members[Nmax];
vector<pii> G[Nmax+5];
vector<int> Adj[Nmax*Tmax+5];
int g[Nmax*Tmax+5][Nmax*Tmax+5];
int tmp,maxflow = 0;
int T[Nmax*Tmax+5];

inline int encode(int t,int i) {
    return t * Nmax + i;
}

bool seen[Nmax*Tmax];

bool bfs()
{
    fill_n(seen,Nmax*Tmax,0);
    queue<int> Q;
    Q.push(Source);
    seen[Source] = 1;
    while (!Q.empty())
    {
        int u = Q.front(); Q.pop();
        if (u == Sink) continue;
        FOREACH(it,Adj[u]) if (!seen[*it] && g[u][*it] > 0) {
            T[*it] = u;
            seen[*it] = 1;
            Q.push(*it);
        }
    }
    return seen[Sink];
}

void FluxMaxim()
{
    int minflow = 0;
    while (bfs()) {
        FOREACH(it,Adj[Sink]) {
            if (!seen[*it] || g[*it][Sink] <= 0) continue;
            T[Sink] = *it;
            minflow = inf;
            for (int j = Sink; j != Source; j = T[j]) minflow = min(minflow,g[T[j]][j]);
            for (int j = Sink; j != Source; j = T[j]) {
                g[T[j]][j] -= minflow;
                g[j][T[j]] += minflow;
            }
            maxflow += minflow;
        }
    }
}

void updateGraph()
{
    FOR(i,2,n) {
        int from = encode(tmp,i);
        FOREACH(it,G[i]) {
            int to = encode(tmp+1,it->fi);
            g[from][to] = it->se; Adj[from].pb(to); Adj[to].pb(from);
        }
    }
    FOR(i,1,n) {
        int newNode = encode(tmp+1,i),oldNode = encode(tmp,i);
        Adj[newNode].pb(oldNode); Adj[oldNode].pb(newNode); g[oldNode][newNode] = inf;
    }
    int newNode = encode(tmp+1,1),oldNode = encode(tmp,1);
    Adj[newNode].pb(Sink); Adj[Sink].pb(newNode); g[newNode][Sink] = inf;
}

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

    fin >> n >> m;
    MEMBERS = 0;
    FOR(i,1,n) fin >> members[i], MEMBERS += members[i];
    while (m--) {
        int x,y,c;
        fin >> x >> y >> c;
        G[x].emplace_back(y,c);
        G[y].emplace_back(x,c);
    }
    FOR(i,1,n) {
        Adj[Source].pb(i); Adj[i].pb(Source);
        g[Source][i] = members[i];
    }
    Adj[1].pb(Sink); Adj[Sink].pb(1); g[1][Sink] = inf;
    tmp = maxflow = 0;
    while (true) {
        FluxMaxim();
        if (maxflow == MEMBERS) {
            fout << tmp; return 0;
        }
        updateGraph();
        tmp++;
    }
}