zoukankan      html  css  js  c++  java
  • 初涉网络流 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
    ",Cal_Max_Flow(1,n+2,n+2));
        }
    
        return 0;
    }
    

  • 相关阅读:
    Atitit (Sketch Filter)素描滤镜的实现  图像处理  attilax总结v2
    JS设置cookie、读取cookie、删除cookie
    Atitit 图像处理30大经典算法attilax总结
    Atitit数据库层次架构表与知识点 attilax 总结
    Atitit 游戏的通常流程 attilax 总结 基于cocos2d api
    Atitti css transition Animation differ区别
    Atitit 图像清晰度 模糊度 检测 识别 评价算法 源码实现attilax总结
    Atitit 全屏模式的cs桌面客户端软件gui h5解决方案 Kiosk模式
    Atitit 混合叠加俩张图片的处理 图像处理解决方案 javafx blend
    Atitit  rgb yuv  hsv HSL 模式和 HSV(HSB) 图像色彩空间的区别
  • 原文地址:https://www.cnblogs.com/mqxnongmin/p/10966684.html
Copyright © 2011-2022 走看看