Pagini recente » Cod sursa (job #167549) | Cod sursa (job #868761) | Cod sursa (job #758499) | Diferente pentru info-oltenia-2018/individual intre reviziile 5 si 6 | Cod sursa (job #1806892)
#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] << " ";
}