Pagini recente » Cod sursa (job #737992) | Cod sursa (job #2631626) | Cod sursa (job #3250010) | Cod sursa (job #3348969) | Cod sursa (job #3352166)
////https://www.infoarena.ro/problema/tribut
//implementare cu lista de adiacenta
#include <fstream>
#include <ios>
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
ifstream fin("tribut.in");
ofstream fout("tribut.out");
struct Edge{
int to,cap,flow,rev;
};
void addEdge(vector<vector<Edge>>&adj,int u , int v,int cap){
adj[u].push_back({v,cap,0,(int)adj[v].size()});
adj[v].push_back({u,0,0,(int)adj[u].size()-1});
}
bool bfs(int source,int sink,const vector<vector<Edge>>& adj,
vector<int>&parentNode,vector<int>&parentEdge){
fill(parentNode.begin(), parentNode.end(), -1);
queue<int>q;
q.push(source);
parentNode[source]= source;
while(!q.empty()){
int u = q.front();
q.pop();
for(int i=0;i<(int)adj[u].size();i++){
const Edge& v = adj[u][i];
if(parentNode[v.to]==-1 && v.cap-v.flow>0){
parentNode[v.to] = u;
parentEdge[v.to] = i;
if(v.to == sink) return true;
q.push(v.to);
}
}
}
return false;
}
void solve(){
int n,m;
fin>>n>>m;
int nodes = n+m+2;
vector<vector<Edge>> adj(nodes);
for(int i=1;i<=n;i++){
int tribut;
fin>>tribut;
addEdge(adj,0,i,tribut);
}
for(int i=n+1;i<=m+n;i++){
int p,tribut;
fin>>p>>tribut;
addEdge(adj, i, n+m+1, tribut);
for(int j=0;j<p;j++){
int node;
fin>>node;
addEdge(adj,node,i,1e9);
}
}
vector<int> parentNode(nodes,-1),parentEdge(nodes);
int maxTribut = 0;
while(bfs(0,nodes-1,adj,parentNode,parentEdge)){
int pathFlow = 1e9;
for(int v = nodes-1;v!=0;v = parentNode[v]){
int u = parentNode[v];
int idx = parentEdge[v];
pathFlow = min(pathFlow,adj[u][idx].cap-adj[u][idx].flow);
}
for(int v = nodes-1;v!=0;v = parentNode[v]){
int u = parentNode[v];
int idx = parentEdge[v];
int revIdx = adj[u][idx].rev;
adj[u][idx].flow+=pathFlow;
adj[v][revIdx].flow-=pathFlow;
}
maxTribut+=pathFlow;
}
fout << maxTribut << '\n';
}
int main(){
//ios_base::sync_with_stdio(false);
//cin.tie(0);
int t;
fin>>t;
while(t--) solve();
return 0;
}