Cod sursa(job #1274196)

Utilizator vlady1997Vlad Bucur vlady1997 Data 23 noiembrie 2014 15:43:23
Problema Flux maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 5.1 kb
        #include <cstdio>
        #include <cstring>
        #include <algorithm>
        #include <vector>
        #include <queue>
        #define INF 1000000
        using namespace std;
        vector <int> g[1001];
        vector <int> :: iterator Vecin;
        queue <int> q;
        int flux[1001][1001], capacitate[1001][1001], heap[1001], poz[1001], tata[1001], cost[1001][1001], Cost[1001], n, sursa, destinatie, nr=0, s=0, CostMin=0, sol;
        bool used[1001];
        void swap (int x, int y)
        {
            int aux=poz[heap[x]];
            poz[heap[x]]=poz[heap[y]];
            poz[heap[y]]=aux;
            aux=heap[x];
            heap[x]=heap[y];
            heap[y]=aux;
        }
        void heapup (int x)
        {
            if (x==1) return;
            if (Cost[heap[x]]<Cost[heap[x/2]])
            {
                swap(x,x/2);
                heapup(x/2);
            }
        }
        void heapdown(int x)
        {
            int st, dr;
            if (x*2>nr) return;
            st=Cost[heap[x*2]];
            if (x*2+1<=nr) dr=Cost[heap[x*2+1]];
            else dr=st+1;
            if (st<dr)
            {
                if (Cost[heap[x]]<=st) return;
                swap(x,x*2);
                heapdown(x*2);
            }
            else
            {
                if (Cost[heap[x]]<=dr) return;
                swap(x,x*2+1);
                heapdown(x*2+1);
            }
        }
        bool dijkstra (void)
        {
            int i, j, Nod;
            for (Nod=1; Nod<=n; Nod++)
            {
                if (Cost[Nod]>=INF) continue;
                for (i=0; i<g[Nod].size(); i++)
                {
                    if (Cost[g[Nod][i]]<INF) cost[Nod][g[Nod][i]]+=Cost[Nod]-Cost[g[Nod][i]];

                }
            }
            memset(Cost,INF,sizeof(Cost)); memset(tata,0,sizeof(tata));
            Cost[sursa]=0;
            for (i=1; i<=n; i++)
            {
                heap[i]=i;
                poz[i]=i;
            }
            swap(1,sursa); nr=n;
            while (nr>0 && Cost[heap[1]]<INF)
            {
                Nod=heap[1];
                swap(1,nr);
                nr--;
                heapdown(1);
                for (j=0; j<g[Nod].size(); j++)
                {
                    if (Cost[g[Nod][j]]>Cost[Nod]+cost[Nod][g[Nod][j]] && flux[Nod][g[Nod][j]]<capacitate[Nod][g[Nod][j]])
                    {
                        Cost[g[Nod][j]]=Cost[Nod]+cost[Nod][g[Nod][j]];
                        tata[g[Nod][j]]=Nod;
                        heapup(poz[g[Nod][j]]);
                    }
                }
            }
            if (Cost[destinatie]<INF) return true;
            else return false;
        }
        void bellmanford (void)
        {
            int nod, i;
            while (!q.empty()) q.pop(); q.push(sursa);
            memset(used,false,sizeof(used)); memset(Cost,INF,sizeof(Cost)); memset(tata,0,sizeof(tata));
            used[sursa]=false; Cost[sursa]=0;
            while (!q.empty())
            {
                nod=q.front();
                q.pop();
                used[nod]=false;
                for (i=0; i<g[nod].size(); i++)
                {
                    if (Cost[nod]+cost[nod][g[nod][i]]<Cost[g[nod][i]] && flux[nod][g[nod][i]]<capacitate[nod][g[nod][i]])
                    {
                        if (Cost[g[nod][i]]>=INF) Cost[g[nod][i]]=Cost[nod]+cost[nod][g[nod][i]];
                        else Cost[g[nod][i]]+=Cost[nod]+cost[nod][g[nod][i]];
                        if (!used[g[nod][i]])
                        {
                            used[g[nod][i]]=true;
                            q.push(g[nod][i]);
                        }
                    }
                }
            }
            s=Cost[destinatie];
        }
        void flux_maxim (void)
        {
            int i, j, r;
            while (dijkstra())
            {
                r=INF;
                for (j=destinatie; j!=sursa; j=tata[j])
                {
                    r=min(r,capacitate[tata[j]][j]-flux[tata[j]][j]);
                }
                for (j=destinatie; j!=sursa; j=tata[j])
                {
                    flux[tata[j]][j]+=r;
                    flux[j][tata[j]]-=r;
                }
                s+=Cost[destinatie];
                CostMin+=r*s;
                sol=CostMin;
            }
        }
        int main()
        {
            int m, i, x, y, z, t;
            freopen("fmcm.in","r",stdin);
            freopen("fmcm.out","w",stdout);
            scanf("%d%d%d%d",&n,&m,&sursa,&destinatie);
            for (i=1; i<=m; i++)
            {
                scanf("%d%d%d%d",&x,&y,&z,&t);
                capacitate[x][y]=z;
                g[x].push_back(y);
                g[y].push_back(x);
                cost[x][y]=t;
                cost[y][x]=-t;
            }
            bellmanford();
            flux_maxim();
            printf("%d",sol);
            fclose(stdin);
            fclose(stdout);
            return 0;
        }