Cod sursa(job #431405)

Utilizator dead_knightTitei Paul Adrian dead_knight Data 31 martie 2010 22:48:56
Problema Cuplaj maxim de cost minim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.2 kb
#include<iostream>
#include<fstream>
#include<cstdio>
#include<deque>
#include<vector>
#define pb push_back
#define pop pop_front
#define maxn 10005
#define newmax 142
#define INFI 2100000000
using namespace std;

vector<int> quex;
int u, k, n, X, ea[maxn], ex[maxn], a[newmax][newmax], cap[newmax][newmax], S, D, rez;
int d[newmax], t[newmax], v[newmax];
vector<int> G[maxn];

void citire();
void bfs(int start);
void construct();

void afis()
{
    int i, j;
    printf("%d %d %d\n", u, k, n);
    for(i=0;i<=D;i++)
    {
        for(j=0;j<=D;j++)
            printf("%2d ", a[i][j]);
        printf("\n");
    }
    printf("\n");
    for(i=0;i<=D;i++)
    {
        for(j=0; j<=D;j++)
            printf("%2d ", cap[i][j]);
        printf("\n");
    }
    printf("\n");
}

int bmf()
{
    vector<int> coada;
    int st, dr, i, nod;
    for(i=0;i<=n+1;i++)
        d[i]=INFI, t[i]=-1, v[i]=0;
    d[S]=0, t[S]=0, v[S]=1;
    st=dr=0;
    coada.pb(S);
    while(st<=dr)
    {
        nod=coada[st++];
        v[nod]=0;
        for(i=0;i<=n+1;i++)
            if( cap[nod][i]>0 && i!=nod && d[i]>d[nod]+a[nod][i] )
            {
                d[i]=d[nod]+a[nod][i];
                t[i]=nod;
                if(v[i]==0)
                {
                    v[i]=1;
                    coada.pb(i);
                    dr++;
                }
            }
    }
    coada.clear();
    return d[D]!=INFI;
}

void fluxu()
{
    int i;
    while(bmf())
    {
        //printf("%d ", D);
        for(i=D;i!=S;i=t[i])
        {
            //printf("%d ", t[i]);
            cap[t[i]][i]-=1;
            cap[i][t[i]]+=1;
        }
        rez+=d[D];
        //printf("   %d\n", d[D]);
    }
}

int main()
{
    int i;
    freopen("atac2.out","w", stdout);
    citire();
    for(i=0;i<quex.size();i++)
        bfs(quex[i]);
    construct();
    //afis();
    fluxu();
    //afis();
    printf("%d", rez);
    return 0;
}

void citire()
{
    int i, m, q1=0, q2;
    ifstream fin("atac2.in");
    fin>>n>>m>>u>>X;
    q2=u;
    for(i=1;i<=u;i++)
    {

        int x;
        fin>>x;
        ea[x]=++q1;
    }
    for(i=1;i<=m;i++)
    {
        int x, y;
        fin>>x>>y;
        G[x].pb(y);
        G[y].pb(x);
    }
    k=G[X].size();
    for(i=0;i<G[X].size();i++)
    {
        ex[G[X][i]]=++q2;
        quex.pb(G[X][i]);
    }
}

void bfs(int start)
{
    int d[maxn];
    deque<int> coada;
    int nod, i;
    for(i=1;i<=n;i++)
        d[i]=-1;
    d[start]=0;
    coada.pb(start);
    while(!coada.empty())
    {
        nod=coada.front();
        coada.pop();
        for(i=0;i<G[nod].size();i++)
            if(d[G[nod][i]]==-1)
            {
                int vecin=G[nod][i];
                d[vecin]=d[nod]+1;
                if(ea[vecin])
                    a[ex[start]][ea[vecin]]=d[vecin], a[ea[vecin]][ex[start]]=-d[vecin], cap[ex[start]][ea[vecin]]=1, cap[ea[vecin]][ex[start]]=0;
                coada.pb(vecin);
            }
    }
}

void construct()
{
    int i;
    n=u+k;
    S=0;
    D=n+1;
    for(i=1;i<=u;i++)
        cap[i][D]=1;
    for(i=u+1;i<=n;i++)
        cap[S][i]=1;
}