Cod sursa(job #3352166)

Utilizator deniscaliuCaliu Denis deniscaliu Data 24 aprilie 2026 16:00:15
Problema Tribut Scor 100
Compilator cpp-64 Status done
Runda Arhiva ICPC Marime 2.57 kb
////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;
}