Cod sursa(job #1845289)

Utilizator PopoviciRobertPopovici Robert PopoviciRobert Data 11 ianuarie 2017 10:00:12
Problema Tribut Scor 100
Compilator cpp Status done
Runda Arhiva ICPC Marime 2.01 kb
#include <bits/stdc++.h>
#define MAXN 101
#define INF 100000000
std::vector <int> G[2*MAXN+1];
int capacity[2*MAXN+1][2*MAXN+1];
int flow[2*MAXN+1][2*MAXN+1];
int Q[2*MAXN+1];
int from[2*MAXN+1];
bool viz[2*MAXN+1];
inline void add_Edge(int a,int b,int c){
   G[a].push_back(b);
   capacity[a][b]=c;
}
inline bool BFS(int S,int D){
    int b,e,x,nod;
    memset(viz,0,sizeof(viz));
    memset(from,0,sizeof(from));
    Q[0]=S;
    viz[S]=1;
    b=0;
    e=1;
    do{
       nod=Q[b];
       for(auto x:G[nod])
        if(viz[x]==0&&capacity[nod][x]>flow[nod][x]){
           from[x]=nod;
           viz[x]=1;
           Q[e]=x;
           e++;
        }
       b++;
    }while(b<e&&viz[D]==0);
    return viz[D];
}
inline int Max_Flow(int S,int D){
    int min,nod,ans;
    ans=0;
    while(BFS(S,D)==1){
       nod=D;
       min=INF;
       while(nod>0){
          if(min>capacity[from[nod]][nod]-flow[from[nod]][nod])
             min=capacity[from[nod]][nod]-flow[from[nod]][nod];
          nod=from[nod];
       }
       nod=D;
       while(nod>0){
          flow[from[nod]][nod]+=min;
          flow[nod][from[nod]]-=min;
          nod=from[nod];
       }
       ans+=min;
    }
    return ans;
}
int main(){
    std::ifstream fin("tribut.in");
    std::ofstream fout("tribut.out");
    int i,n,m,j,t,nodes,cap,S,D,k,nod;
    fin >> t;
    while(t>0){
       t--;
       memset(flow,0,sizeof(flow));
       memset(capacity,0,sizeof(capacity));
       fin >> n >> m;
       S=0;
       D=n+m+1;
       for(i=1;i<=n;i++){
          fin >> cap;
          add_Edge(S,i,cap);
          add_Edge(i,S,0);
       }
       nodes=n;
       for(i=1;i<=m;i++){
          fin >> k >> cap;
          nodes++;
          for(j=1;j<=k;j++){
             fin >> nod;
             add_Edge(nod,nodes,INF);
             add_Edge(nodes,nod,0);
          }
          add_Edge(nodes,D,cap);
          add_Edge(D,nodes,0);
       }
       fout << Max_Flow(S,D) << "\n";
       for(i=0;i<=nodes+1;i++)
         G[i].clear();
    }
    fin.close();
    fout.close();
    return 0;
}