Cod sursa(job #1709708)

Utilizator UPB_CodeJunkiesUPB NAIDEN NICOLICIOIU COTET UPB_CodeJunkies Data 28 mai 2016 13:32:56
Problema Tribut Scor 100
Compilator cpp Status done
Runda ONIS 2016 - Runda - 2 - ACM ICPC Romanian Programming Contest Marime 2.68 kb
#include<stdio.h>
#include<algorithm>
#include<queue>

#define pb push_back
#define maxn 305
#define inf 0x3f3f3f3f
using namespace std;

int T;
int n,m,S,D,flow,nr=1;

int used[maxn],father[maxn];
int c[maxn][maxn],f[maxn][maxn];

int tribut[maxn];
int tribut_tara[maxn];
vector<int> l[maxn];

void read()
{
    scanf("%d%d",&n,&m);

    for(int i=1;i<=n;i++) scanf("%d",&tribut[i]);

    int P,x;
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d",&P,&tribut_tara[2*n+i]);
        for(int j=1;j<=P;j++)
        {
            scanf("%d",&x);
            c[n+x][2*n+i]=tribut[x];

            l[n+x].pb(2*n+i);
            l[2*n+i].pb(n+x);
        }
    }

    S=0; D=2*n+m+1;

    for(int i=1;i<=n;i++)
    {
        c[S][i]=inf;

        l[S].pb(i);
        l[i].pb(S);
    }

    for(int i=1;i<=n;i++)
    {
        c[i][n+i]=tribut[i];

        l[i].pb(n+i);
        l[n+i].pb(i);
    }

    for(int i=2*n+1;i<=2*n+m;i++)
    {
        c[i][D]=tribut_tara[i];

        l[i].pb(D);
        l[D].pb(i);
    }
}

int bfs()
{
    int k;
    queue <int> q;

    q.push(0); used[0]=nr;
    for(;!q.empty();)
    {
        k=q.front();
        if(k==D) {q.pop(); continue;}

        for(unsigned int i=0;i<l[k].size();i++)
           if(used[l[k][i]]!=nr && f[k][l[k][i]]<c[k][l[k][i]])
           {
               q.push(l[k][i]);
               used[l[k][i]]=nr;

               father[l[k][i]]=k;
           }
           q.pop();
    }
    return used[D];
}

void solve()
{
    int Min;

    while(bfs()==nr)
    {
        for(unsigned int i=0;i<l[D].size();i++)
           if(used[l[D][i]]==nr && f[l[D][i]][D]<c[l[D][i]][D])
           {
               father[D]=l[D][i];

               Min=inf;
               for(int j=D;father[j]!=0;j=father[j])
                 if(Min> c[father[j]][j]-f[father[j]][j])
                    Min=c[father[j]][j]-f[father[j]][j];

                for(int j=D;father[j]!=0;j=father[j])
                {
                    f[father[j]][j]+=Min;
                    f[j][father[j]]-=Min;
                }

              flow+=Min;
           }
        nr++;
    }
}

void clear_data()
{
    nr=1; flow=0;
    for(int i=S;i<=D;i++)
     for(int j=S;j<=D;j++)
      c[i][j]=f[i][j]=0;

    for(int i=S;i<=D;i++)
    {
        used[i]=father[i]=0;
        l[i].clear();
    }
}

int main()
{
    freopen("tribut.in","r",stdin);
    freopen("tribut.out","w",stdout);

    scanf("%d",&T);
    for(;T;T--)
    {
        read();
        solve();
        printf("%d\n",flow);
        clear_data();
    }

    fclose(stdin);
    fclose(stdout);
    return 0;
}