Cod sursa(job #1806892)

Utilizator tudi98Cozma Tudor tudi98 Data 15 noiembrie 2016 19:54:53
Problema Flux maxim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.95 kb
#include <bits/stdc++.h>
using namespace std;

const int Nmax = 50;
const int NodesMax = Nmax*(Nmax-1)/2+3;
const int inf = 1000000001;

int N;
int W[Nmax],R[Nmax][Nmax];
int Sol[Nmax];
int SolSize = 0,sink = 0,source = 0;
int Nodes = 0;

vector<int> G[NodesMax];
int capacity[NodesMax][NodesMax];
int flow[NodesMax][NodesMax];
bool seen[NodesMax];
int T[NodesMax];
int WINS = 0;

void BuildGraph(int x)
{
    Nodes = N * (N - 1) / 2 + 3;
    sink = Nodes - 1;
    source = Nodes - 2;

    for (int i = 0; i < Nodes; i++)
        G[i].clear();

    for (int i = 0; i < Nodes; i++)
        for (int j = 0; j < Nodes; j++)
            capacity[i][j] = flow[i][j] = 0;

    int cnode = N;
    for (int i = 0; i < N; i++)
        for (int j = i+1; j < N; j++)
        {
            if (i == x || j == x) continue;
            G[source].push_back(cnode);
            G[cnode].push_back(i);
            G[cnode].push_back(j);
            G[i].push_back(cnode);
            G[j].push_back(cnode);
            G[cnode].push_back(source);
            capacity[source][cnode] = R[i][j];
            capacity[cnode][i] = inf;
            capacity[cnode][j] = inf;
       //     cout << capacity[source][cnode] << " of " << source << " -> " << cnode << " sink \n";
            cnode++;
        }
  //  cout << "Graph:\n" << WINS << "\n";;
    for (int i = 0; i < N; i++)
    {
        if (i == x) continue;
        G[i].push_back(sink);
        G[sink].push_back(i);
        capacity[i][sink] = WINS - W[i];
     //   cout << capacity[i][sink] << " of " << i << " -> " << sink << " sink\n";
    }
}

bool bfs()
{
    fill_n(seen,NodesMax,0);
    queue<int> Q;
    Q.push(source);
    seen[source] = 1;

    while (!Q.empty())
    {
        int u = Q.front(); Q.pop();
        if (u == sink) continue;
        for (int i = 0; i < G[u].size(); i++)
        {
            int v = G[u][i];
            if (seen[v] || capacity[u][v] == flow[u][v]) continue;
            T[v] = u;
            seen[v] = 1;
            Q.push(v);
        }
    }
    return seen[sink];
}

int MaxFLow()
{
    int maxflow = 0;
    while (bfs())
    {
        for (int i = 0; i < G[sink].size(); i++)
        {
            int u = G[sink][i];
            if (!seen[u] || flow[u][sink] == capacity[u][sink]) continue;
            int minflow = inf;
            T[sink] = u;
            for (int k = sink; k != source; k = T[k])
                minflow = min(minflow,capacity[T[k]][k] - flow[T[k]][k]);

            if (!minflow) continue;

            for (int k = sink; k != source; k = T[k])
            {
                flow[T[k]][k] += minflow;
                flow[k][T[k]] -= minflow;
            }

            maxflow += minflow;
        }
    }
    return maxflow;
}

bool canWin(int x)
{
    WINS = W[x];
    for (int i = 0; i < N; i++)
        WINS += R[x][i];
    for (int i = 0; i < N; i++)
        if (WINS < W[i]) return 0;
    BuildGraph(x);
    int mleft = 0;
    for (int i = 0; i < N; i++)
        for (int j = i+1; j < N; j++)
            if (i != x && j != x)
                mleft += R[i][j];
    //cout << mleft << " left\n";
    //cout << MaxFLow() << " flow\n";
    /*for (int i = 0; i < 8; i++)
        for (int j = 0; j < 8; j++)
            cout << "flow from " << i << " to " << j << " = " << flow[i][j] << "\n";
    */if (MaxFLow() == mleft)
        return 1;
    return 0;
}

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

    fin >> N;
    for (int i = 0; i < N; i++)
        fin >> W[i];

    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            fin >> R[i][j];

    for (int player = 0; player < N; player++)
    {
        if (canWin(player))
        {
            SolSize++;
            Sol[SolSize-1] = player;
        }
    }

    fout << SolSize << "\n";
    for (int i = 0; i < SolSize; i++)
        fout << Sol[i] << " ";
}