Dijkstra's minimum cost maximum flow problem

           For minimum-cost flow problem, its focus lies in "augmented road" What is augmenting path? Is the basis to find a way of adding more plus a road to make the road a result, the direct use of road Dijkstra able to find the shortest path, continue to use the smallest way to find the remaining middle of the road, but the two roads come together is not necessarily the overall minimum road for the first time 1 -> 3 -> 5-> 4-> 6 second 1-> 2-> 6 this is not the result we need, so when looking for the second shortest path, we need to be able to go back, can not

So that for the first time do not go 3-> 5, how to go back, plus a counter-edge at the time of constructing a map, for the first time taking the number of positive sides to reduce the number of anti-edge plus much, so you can take a second 5-> 3 then go 3-> 6 this line, the first pass 3-> 5, the second scrape 5-> considerable first path and go back 3, so that the road can take the minimum possible.

#include <the iostream> 
#include <CString> 
#include <Queue> 
the using namespace STD; 
/ * 2. 6. 11. 1. 1. 3 23 is 12 is 99 2. 5. 1. 4. 17 2. 6. 3. 3. 5. 6. 3 73 is 21 is 33 is 2. 4. 5. 6. 8 20 is. 5. 4. 5. 6. 5 * / 
#define MAX 23060 
int MinCos; 
int V, CNT; 
int Head [MAX]; 
int the Next [MAX]; 
int F. [MAX]; // flow 
int To [MAX]; // end the 
int Dis [MAX]; 
int Cos [MAX]; // takes 
int VIS [MAX]; 
void _add (int a, int B, int F, int C) 
{ 
    CNT ++; 
    F. [CNT] = F; 
    the to [CNT ] = B; 
    Cos [CNT] = C; 
    the Next [CNT] Head = [A]; 
    Head [A] = CNT; 
} 
void the Add (A int, int B, int C) // point increase for patterning 
{
    if(!vis[a]&&a!=1&&a!=v)
    {
        _add(a,a+v,1,0);
        _add(a+v,a,0,0);
        vis[a]=1;
    }
    if(!vis[b]&&b!=1&&b!=v)
    {
        _add(b,b+v,1,0);
        _add(b+v,b,0,0);
        vis[b]=1;
    }
    if(a==1||b==v)
    {
        if(a!=1&&b==v)
        {
            _add(a+v,b,1,c);
            _add(b,a+v,0,-c);
        }else if(a==1&&b!=v)
        {
            _add(a,b,1,c);
            _add(b,a,0,-c);
        }
        else
        {
            _add(a,b,1,c);
            _add(b,a,0,-c);
        }
    }else if(a==v||b==1){}
    else
    {
        _add(a+v,b,1,c);
        _add(b,a+v,0,-c);
    }
}
void Dijks(int folw)//Dijks求最小费用最大流算法
{
    priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >sp;
    int h[MAX];
    To[MAX-1]=1;
    memset(h,0,sizeof(h));
    while(folw>0) {
        memset(Dis, 0x3f3f3f3f, sizeof(Dis));
        memset(vis,0,sizeof(vis));
        Dis[1] = 0;
        pair<int, int> t;
        sp.push(make_pair(0,MAX-1));
        int pre[MAX];
        pre[1] = 0;
        while (!sp.empty()) {
            t = sp.top();
            sp.pop();
            int to = To[t.second];
            if(to==v)continue;
            if(vis[to])continue;
            if (Dis[to] < t.first)continue;//剪枝
            vis[to]=1;
            for (int i = Head[to]; i != -1; i = Next[i]) {
                if (F[i] && Dis[To[i]] > Dis[to] + h[to] - h[To[i]] + Cos[i]) {//跟新最小费用
                    Dis[To[i]] = Dis[to] + h[to] - h[To[i]] + Cos[i];
                    pre[i]=t.second;//记录上一个节点
                    if(To[i]==v)
                    {
                        pre[MAX-2]=i;
                    }
                    sp.push(make_pair(Dis[To[i]], i));
                }
            } 
            F. [I] = 0;
        }
        IF (Dis [V] == 0x3f3f3f3f) BREAK; 
        for (int I =. 1; I <= 2 * V; I ++) { 
            H [I] + = Dis [I]; // I do not understand, but an article blog write particularly 
        } 
        for (int I = pre [MAX-2]; I = MAX-. 1; I = pre [I]!) // find the minimum cost 
        { 
            MinCos + = Cos [I]; 
            F. [I] - = 1; // logging data when zero, the forward edge of the even-numbered memory, the reverse side of the odd- 
            F [i ^ 1] + = 1; // i ^ 1 is odd 
        } 
        Folw - = 1; 
    } 
    COUT << MinCos << "\ n-"; 
} 
int main () 
{ 
    iOS :: sync_with_stdio (to false); 
    cin.tie (0); 
    int P; 
    the while (V >> >> P CIN) { 
        for (int I = 0; I <20060; I ++) 
        { 
            the To [I] = 0;
            Dis[i]=0;
            Cos[i]=0;
            vis[i]=0;
            Head[i]=-1;
            Next[i]=-1;
        }
        MinCos=0;
        cnt=-1;
        for (int i = 0; i < p; i++) {
            int a, b, c;
            cin >> a >> b >> c;
            add(a, b, c);
        }
        Dijks(2);
    }
    return 0;
}

 Blog http://www.cppblog.com/guojingjia2006/archive/2009/11/12/57905.html a big brother to explain h [i] function

Guess you like

Origin www.cnblogs.com/hycn/p/11329955.html