Cod sursa(job #1653584)

Utilizator GinguIonutGinguIonut GinguIonut Data 16 martie 2016 11:28:41
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.87 kb
#include <fstream>
#include <queue>
#include <vector>
#include <string.h>
#define INF 0x3f3f3f3f
#define nMax 205
#define S 0
#define D 203
#define pb push_back
#define mkp make_pair
using namespace std;
ifstream fin("cc.in");
ofstream fout("cc.out");
int n, Cost[nMax][nMax], C[nMax][nMax], flow, flowCost, d[nMax], viz[nMax], real_d[nMax], old_d[nMax], TT[nMax];
vector<int> G[nMax];
queue<int> Q;
priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > H;
void read()
{
    fin>>n;
    for(int i=1;i<=n;i++)
    {
        for(int j=n+1;j<=2*n;j++)
        {
            fin>>Cost[i][j];
            Cost[j][i]=-Cost[i][j];
            C[i][j]=1;
            G[i].pb(j);
            G[j].pb(i);
        }
    }
    for(int i=1;i<=n;i++)
    {
        G[S].pb(i);
        C[S][i]=1;
        G[i+n].pb(D);
        C[i+n][D]=1;
    }
}
inline bool dijkstra()
{
    memset(d, INF, sizeof(d));
    d[S]=0, real_d[S]=0;
    for(H.push(mkp(d[S], S));!H.empty();)
    {
        int cost=H.top().first;
        int node=H.top().second;
        H.pop();
        if(d[node]!=cost)
            continue;
        for(vector<int>::iterator it=G[node].begin();it!=G[node].end();it++)
        {
            int fiu=*it;
            if(C[node][fiu]==0)
                continue;
            int new_d=d[node]+old_d[node]+Cost[node][fiu]-old_d[fiu];
            if(new_d<d[fiu])
            {
                d[fiu]=new_d;
                real_d[fiu]=real_d[node]+Cost[node][fiu];
                TT[fiu]=node;
                H.push(mkp(d[fiu], fiu));
            }
        }
    }
    memcpy(old_d, real_d, sizeof(old_d));
    if(d[D]==INF)
        return 0;
    return 1;
}
void bellman_ford()
{
    memset(old_d, INF, sizeof(old_d));
    old_d[S]=0;
    for(Q.push(S);!Q.empty();Q.pop())
    {
        int node=Q.front();
        viz[node]=0;
        for(vector<int>::iterator it=G[node].begin();it!=G[node].end();it++)
        {
            int fiu=*it;
            if(C[node][fiu]==0)
                continue;
            if(old_d[node]+Cost[node][fiu]<old_d[fiu])
            {
                TT[fiu]=node;
                old_d[fiu]=old_d[node]+Cost[node][fiu];
                if(viz[fiu]==0)
                {
                    viz[fiu]=1;
                    Q.push(fiu);
                }
            }
        }
    }
}
void solve()
{
    bellman_ford();
    while(dijkstra())
    {
        int Min=INF;
        for(int aux=D;aux!=S;aux=TT[aux])
            Min=min(Min, C[TT[aux]][aux]);
        for(int aux=D;aux!=S;aux=TT[aux])
        {
            C[TT[aux]][aux]-=Min;
            C[aux][TT[aux]]+=Min;
        }
        flow+=Min;
        flowCost+=Min*real_d[D];
    }
}
void write()
{
    fout<<flowCost;
}
int main()
{
    read();
    solve();
    write();
    return 0;
}