初涉网络流 POJ 1459 Power Network

Posted mqxnongmin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初涉网络流 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;


以上是关于初涉网络流 POJ 1459 Power Network的主要内容,如果未能解决你的问题,请参考以下文章

POJ1459 Power Network(网络最大流)

Poj1459 Power Network 预流推进

POJ-1459 Power Network(最大流模板)

poj 1459(网络流)

poj-1459-最大流dinic+链式前向星

Edmonds-Karp算法,最大流POJ(1459)