Cod sursa(job #577925)

Utilizator PavelRazvanPavel Razvan PavelRazvan Data 10 aprilie 2011 19:42:39
Problema Cuplaj maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 3.65 kb
#include<algorithm>
using namespace std;
#include<vector>
#include<queue>

#define DIM 305+305+5
#define DIMb 12345
#define pb push_back
#define mp make_pair
#define fs first
#define sc second

vector <pair <short,short> > lst[DIM];
bool vol[DIM][DIM];
short f[DIM][DIM],n,m,t[DIM],s1,s2,poz;
int sol1,sol2,d[DIM],muc[DIM][DIM];
char buff[DIMb];

inline void pars (short &nr)
{
    bool smn=0;
    nr=0;
    while((buff[poz]<'0' || buff[poz]>'9') && buff[poz]!='-')
        if(++poz==DIMb)
            fread (buff,1,DIMb,stdin),poz=0;

    while((buff[poz]>='0' && buff[poz]<='9') || buff[poz]=='-')
    {
        if(buff[poz]=='-')
            smn=1;
        else
            nr=nr*10+buff[poz]-'0';

        if(++poz==DIMb)
            fread (buff,1,DIMb,stdin),poz=0;
    }
    if(smn==1)
        nr=-nr;
}
inline void pars2 (int &nr)
{
    nr=0;
    while((buff[poz]<'0' || buff[poz]>'9') && buff[poz]!='-')
        if(++poz==DIMb)
            fread (buff,1,DIMb,stdin),poz=0;

    while((buff[poz]>='0' && buff[poz]<='9') || buff[poz]=='-')
    {
        nr=nr*10+buff[poz]-'0';
        if(++poz==DIMb)
            fread (buff,1,DIMb,stdin),poz=0;
    }
}
struct cmp
{
    bool operator() (const short &a, const short &b) const
    {
        return d[a]>d[b];
    }
}; priority_queue <short, vector <short>,cmp> h;

inline void read ()
{
    short i,nr1,nr2,nr3;
    int nr;

    pars(n);
    pars(m);
    pars2(nr);
    for(i=1;i<=nr;++i)
    {
        pars(nr1);
        pars(nr2);
        pars(nr3);

        ++nr1;
        nr2+=n+1;
        vol[nr1][nr2]=1;
        muc[nr1][nr2]=i;
        lst[nr1].pb (mp(nr2,nr3));
        lst[nr2].pb (mp(nr1,-nr3));
    }
}

inline void graph_builder ()
{
    int i;
    for(i=2;i<=n+1;++i)
    {
        vol[1][i]=1;
        lst[1].pb (mp (i,0));
        lst[i].pb (mp (1,0));
    }
    for(i=n+2;i<=n+m+1;++i)
    {
        vol[i][n+m+2]=1;
        lst[i].pb (mp (n+m+2,0));
        lst[n+m+2].pb (mp (i,0));
    }
    s1=1;
    s2=n+m+2;
}

inline bool dijkstra ()
{
    short i,nr;
    bool v[DIM];
    memset (v,0,sizeof (v));
    for(i=1;i<=s2;++i)
        d[i]=1<<30;

    v[s1]=1;
    d[s1]=0;
    h.push(s1);

    while(!h.empty ())
    {
        nr=h.top ();
        v[nr]=0;
        h.pop ();
        for(i=0;i<lst[nr].size ();++i)
            if(vol[nr][lst[nr][i].fs]!=f[nr][lst[nr][i].fs] && d[nr]+lst[nr][i].sc<d[lst[nr][i].fs])
            {
                d[lst[nr][i].fs]=d[nr]+lst[nr][i].sc;
                t[lst[nr][i].fs]=nr;
                if(v[lst[nr][i].fs]==0)
                {
                    h.push(lst[nr][i].fs);
                    v[lst[nr][i].fs]=1;
                }
            }
    }
    if(d[s2]==1<<30)
        return 0;
    return 1;
}

inline void solve ()
{
    short j,minim;

    graph_builder ();
    while(dijkstra())
    {
        minim=20;
        for(j=s2;j!=s1;j=t[j])
            if(minim>vol[t[j]][j]-f[t[j]][j])
                minim=vol[t[j]][j]-f[t[j]][j];

        sol2+=minim*d[s2];
        for(j=s2;j!=s1;j=t[j])
        {
            f[t[j]][j]+=minim;
            f[j][t[j]]-=minim;
        }
    }
}
int main ()
{
    freopen("cmcm.in","r",stdin);
    freopen("cmcm.out","w",stdout);
    read ();
    solve ();
    for(int i=2;i<=n+1;++i)
        for(int j=n+2;j<=m+n+1;++j)
            if(f[i][j]==1 && vol[i][j]==1)
                ++sol1;

    printf("%hd %hd\n",sol1,sol2);
    for(int i=2;i<=n+1;++i)
        for(int j=n+2;j<=m+n+1;++j)
            if(f[i][j]==1 && vol[i][j]==1)
                printf("%hd ",muc[i][j]);
    return 0;
}