
/*
**  This file forms part of the GOBLIN C++ Class Library.
**
**  Written by Christian Fremuth-Paeger, January 2000.
**  
**  Copying, compiling, distribution and modification
**  of this source code is permitted only in accordance
**  with the GOBLIN general licence information.
*/             


#if !defined(_SPSBAL_H_)

#define _SPSBAL_H_

#include <absbal.h>
#include <spsstruc.h>


class balancedFNW : public abstractBalancedFNW
{                                        
    friend class sparseGraphStructure;
    
protected:
        
    sparseGraphStructure X;    

public:

    balancedFNW(TNode nn,TOption options=0,
        goblinController &thisContext = goblinDefaultContext) throw();
    balancedFNW(char* impFileName,
        goblinController &thisContext = goblinDefaultContext)
        throw(ERFile,ERParse);
    balancedFNW(abstractDiGraph &G,TNode s,TNode t) throw();
    ~balancedFNW() throw();

    unsigned long   Size() throw();     
    unsigned long   Allocated() throw();     
    virtual objectType ClassID() throw() {return IDBalancedFNW;};
    virtual void*   BackCast() {return (void*)this;};
    
    TArc InsertArc(TNode u,TNode v) throw(ERRange,ERRejected)
    {
        ReleaseAdjacencies();
        m++;
        X.InsertArc(v^1,u^1,X.MaxUCap(),0,X.MaxLength());
        m++;
        return X.InsertArc(u,v,X.MaxUCap(),0,X.MaxLength());
    };

    TArc InsertArc(TNode u,TNode v,TCap uu,TFloat cc) throw(ERRange,ERRejected)
    {
        ReleaseAdjacencies();
        m++;
        X.InsertArc(v^1,u^1,uu,0,cc);
        m++;
        return X.InsertArc(u,v,uu,0,cc);
    };
    
    TArc InsertArc(TNode u,TNode v,TCap uu,TCap ll,TFloat cc) throw(ERRange,ERRejected)
    {
        ReleaseAdjacencies();
        m++;
        X.InsertArc(v^1,u^1,uu,ll,cc);
        m++;
        return X.InsertArc(u,v,uu,ll,cc);
    };
    
    void            Symmetrize() throw();
    void            Relax() throw();

    #include <spsincl.h>

    TFloat          Length(TArc a) throw(ERRange);
    TFloat          BalFlow(TArc a) throw(ERRange)
                        {return X.Flow(a);};
    void            BalPush(TArc a,TFloat Lambda) throw(ERRange)
                        {Push(a,Lambda); Push(a^2,Lambda);};

};                             


class splitGraph : public balancedFNW
{                                        
public:

    splitGraph(abstractDiGraph &G,TNode s,TNode t) throw();
    
    TNode Source() throw() {return n-1;};
    TNode Target() throw() {return n-2;};

};

#endif
