首页 > 代码库 > 初涉网络流 POJ 1459 Power Network

初涉网络流 POJ 1459 Power Network

怒搞一下午网络流,又去我一块心病。

从2F到SAP再到Dinic终于过掉了。可是书上说Dinic的时间复杂度为v*v*e。感觉也应该超时的啊,可是过掉了,好诡异。

后两种算法都是在第一种的基础上进行优化。第一种方法就是不停的寻找增广路,后两种引进了层次网络的概念,第三种又改善了寻找增广路的方法。

现在只能理解到这里了。。。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <stack>
#include <map>

#pragma comment(linker, "/STACK:1024000000");
#define EPS (1e-8)
#define LL long long
#define ULL unsigned long long
#define _LL __int64
#define _INF 0x3f3f3f3f
#define Mod 6000007

using namespace std;

struct E
{
    int u,v,Max,now,next;
}edge[30000];

int Top;

int head[300];

void Link(int u,int v,int w)
{
    edge[Top].u = u;
    edge[Top].v = v;
    edge[Top].Max = w;
    edge[Top].now = 0;
    edge[Top].next = head[u];
    head[u] = Top++;
}

struct P
{
    int pre,now,floor;
    bool mark;
}sta[300];

void Modify(int a,int t)
{
    while(t != 1)
    {
        edge[sta[t].pre].now += a;
        t = edge[sta[t].pre].u;
    }
}

int SAP(int s,int t,int n)
{
    for(int i = 1;i <= n; ++i)
        sta[i].mark = false;

    queue<int> q;

    q.push(s);

    sta[s].mark = true;
    sta[s].now = 2000000000;
    sta[s].pre = -1;

    while(q.empty() == false)
    {
        if(sta[t].mark && sta[t].now)
        {
            Modify(sta[t].now,t);
            return sta[t].now;
        }

        int f = q.front();
        q.pop();

        for(int p = head[f];p != -1; p = edge[p].next)
        {
            if(sta[edge[p].v].mark == false && sta[edge[p].u].floor == sta[edge[p].v].floor-1 && sta[edge[p].u].floor < sta[t].floor)
            {
                sta[edge[p].v].now = min(sta[f].now,edge[p].Max - edge[p].now);
                if(sta[edge[p].v].now == 0)
                    continue;
                sta[edge[p].v].pre = p;//记录边的存储位置
                sta[edge[p].v].mark = true;
                q.push(edge[p].v);
            }
        }

    }

    return 0;
}

void Updata_Floor(int s,int t,int n)
{
    queue<int> q;

    for(int i = 0;i <= n; ++i)
        sta[i].mark = false,sta[i].floor = n;

    q.push(s);
    sta[s].mark = true;
    sta[s].floor = 1;

    while(q.empty() == false)
    {
        int f = q.front();
        q.pop();

        if(sta[t].mark && sta[t].floor <= sta[f].floor)
            return ;
        for(int p = head[f];p != -1; p = edge[p].next)
        {
            if(sta[edge[p].v].mark == false && edge[p].now < edge[p].Max)
            {
                sta[edge[p].v].mark = true;
                sta[edge[p].v].floor = sta[f].floor + 1;
                q.push(edge[p].v);
            }
        }
    }
}

int dfs(int s,int t,int a)
{
    if(s == t)
        return a;

    int f = 0;

    for(int p = head[s],temp = 0;p != -1; p = edge[p].next)
    {
        if((sta[edge[p].v].floor < sta[t].floor || edge[p].v == t) && sta[edge[p].v].floor == sta[s].floor+1 && edge[p].now < edge[p].Max)
        {
            temp = dfs(edge[p].v,t,min(a-f,edge[p].Max-edge[p].now));
            edge[p].now += temp;
            f += temp;
        }
    }
    return f;
}

int Dinic(int s,int t,int n)
{
    return dfs(s,t,200000000);
}

int Cal_Max_Flow(int s,int t,int n)
{
    int temp,f = 0;

    do
    {
        Updata_Floor(s,t,n);
        //temp = SAP(s,t,n);
        temp = Dinic(s,t,n);
        f += temp;
    }while(temp);

    return f;
}

int main()
{
    char s[50];
    int i,n,np,nc,m,u,v,w;

    while(scanf("%d %d %d %d",&n,&np,&nc,&m) != EOF)
    {
        memset(head,-1,sizeof(head));
        Top = 0;

        for(i = 0;i < m; ++i)
        {
            scanf("%s",s);
            sscanf(s,"(%d,%d)%d",&u,&v,&w);
            Link(u+2,v+2,w);
        }

        for(i = 0;i < np; ++i)
        {
            scanf("%s",s);
            sscanf(s,"(%d)%d",&u,&w);
            Link(1,u+2,w);
       }

        for(i = 0;i < nc; ++i)
        {
            scanf("%s",s);
            sscanf(s,"(%d)%d",&u,&w);
            Link(u+2,n+2,w);

        }

        printf("%d\n",Cal_Max_Flow(1,n+2,n+2));
    }

    return 0;
}