Pagini recente » Cod sursa (job #2746287) | Cod sursa (job #1166234) | Cod sursa (job #2934586) | Cod sursa (job #3172107) | Cod sursa (job #1709519)
#include <fstream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int N_MAX = 505;
int N, M, S, D;
vector<int> graph[N_MAX];
int cap[N_MAX][N_MAX];
int flow[N_MAX][N_MAX];
inline int PlanetIn(int x) {
return x;
}
inline int PlanetOut(int x) {
return N + x;
}
inline int Union(int x) {
return 2 * N + x;
}
inline void AddEdge(int x, int y, int c) {
graph[x].push_back(y);
graph[y].push_back(x);
cap[x][y] = c;
}
int dist[N_MAX];
int father[N_MAX];
bool visited[N_MAX];
queue<int> q;
bool Bfs() {
fill(dist, dist + N_MAX, numeric_limits<int> :: max());
fill(father, father + N_MAX, -1);
fill(visited, visited + N_MAX, 0);
visited[S] = 1;
father[S] = S;
dist[S] = 0;
for(q.push(S); !q.empty(); q.pop()) {
int x = q.front();
if(x != D) {
for(vector<int> :: iterator it = graph[x].begin(); it != graph[x].end(); ++it) {
if(flow[x][*it] < cap[x][*it] && !visited[*it]) {
visited[*it] = 1;
dist[*it] = dist[x] + 1;
father[*it] = x;
q.push(*it);
}
}
}
}
return visited[D];
}
int maxFlow;
bool IncreaseFlow() {
if(!Bfs())
return 0;
for(vector<int> :: iterator it = graph[D].begin(); it != graph[D].end(); it++) {
if(visited[*it]) {
father[D] = *it;
int thisFlow = numeric_limits<int> :: max();
for(int i = D; i != S; i = father[i])
thisFlow = min(thisFlow, cap[father[i]][i] - flow[father[i]][i]);
for(int i = D; i != S; i = father[i])
flow[father[i]][i] += thisFlow, flow[i][father[i]] -= thisFlow;
maxFlow += thisFlow;
}
}
return 1;
}
int v[N_MAX];
int vUnion[N_MAX];
bool inUnion[N_MAX];
void Reset() {
fill(v, v + N_MAX, 0);
fill(vUnion, vUnion + N_MAX, 0);
fill(inUnion, inUnion + N_MAX, 0);
for(int i = 0; i < N_MAX; i++) {
for(int j = 0; j < N_MAX; j++) {
cap[i][j] = 0;
flow[i][j] = 0;
}
}
for(int i = 0; i < N_MAX; i++)
graph[i].clear();
S = 0;
D = N_MAX - 1;
maxFlow = 0;
}
int main() {
ifstream f("tribut.in");
ofstream g("tribut.out");
int T;
f >> T;
while(T--) {
Reset();
f >> N >> M;
for(int i = 1; i <= N; i++) {
f >> v[i];
AddEdge(PlanetIn(i), PlanetOut(i), v[i]);
}
for(int i = 1, cnt; i <= M; i++) {
f >> cnt >> vUnion[i];
for(int j = 1, x; j <= cnt; j++) {
f >> x;
inUnion[x] = 1;
AddEdge(PlanetOut(x), Union(i), v[j]);
}
}
for(int i = 1; i <= N; i++)
AddEdge(S, PlanetIn(i), v[i]);
for(int i = 1; i <= M; i++)
AddEdge(Union(i), D, vUnion[i]);
while(IncreaseFlow());
g << maxFlow << '\n';
}
return 0;
}