• 网络流入门的心得


    一、一句话描述网络流问题

      有向图,有多重边,每条边上有容量限制。指定起点和终点,求从起点到终点的最大容量。

    二、一句话描述基本网络算法

      残量网络:考虑有向边,如果通过了正向流量,则消耗正向容量。同时增加反向流量。
      增广路径:考虑有向图,如果能够找到一条路,在当前流量状态下,能够从开始走到结束,且路径经过的最小容量大于零,则认为可以选择这条路径作为答案。
      最大流:每次找到“增广路径”,都将答案更新至残量网络中。直到某一次在完成搜索之后没能找到一条增广路径

    三、一句话描述遇到的坑

      最开始看到增广路径概念之后把网络流当成了无向图模型。

    四、一个列表表示网络流基础算法可以过得题

      http://hihocoder.com/problemset/problem/1369  

      http://acm.hdu.edu.cn/showproblem.php?pid=3549  

      http://poj.org/problem?id=1273

    五、差不多通用的代码:

    #include<iostream>
    #include<stdio.h>
    #include<string>
    #include<vector>
    #include<queue>
    #include<string.h>
    #include<math.h>
    
    using namespace std;
    
    #define ll long long
    #define pp pair<ll,ll>
    #define vecp vector<pp>
    #define veci vector<int>
    
    const ll MAXN=500+233;
    const ll INF = 50000000+23333;
     
    
    class edge
    {
        public :
            ll a,b,c;
            edge(ll a,ll b,ll c)
            {
                this->a=a;
                this->b=b;
                this->c=c;
            }
            edge(){}
    };
    
    veci G[MAXN];
    vector<edge> path;
    ll vis[MAXN];
    ll n,m;
    
    
    void add_edge(ll a,ll b,ll c)
    {
        // path.push_back(make)
        path.push_back(edge(a,b,c));
        G[a].push_back(path.size()-1);
        path.push_back(edge(b,a,0));
        G[b].push_back(path.size()-1);
        
    }
    ll dfs(ll now,ll minn)
    {
        if(vis[now]||minn <= 0 )return 0;
        vis[now]=1;
        if(now == n)return minn;
        ll len = G[now].size();
        
        for(ll i=0;i<len;++i)
        {
            ll pos = G[now][i];
            ll tar = path[pos].b;
            ll mm = min(path[pos].c,minn);
            ll res = dfs(tar,mm);
            if(res)
            {
                path[pos].c -= res;
                path[pos^1].c += res;
                return res;
            }
        }return 0;
    }
    ll cases=0;
    
    void init()
    {
        cases++;
        for(ll i=0;i<=n;++i)G[i].clear();
        path.clear();
        memset(vis,0,sizeof(vis));
        
        for(ll i=0;i<m;++i)
        {
            ll a,b,c;
            cin>>a>>b>>c;
            add_edge(a,b,c);
        }
        
        ll res = dfs(1,INF);
        ll ans = res;
        while(res)
        {
            memset(vis,0,sizeof(vis));
            res = dfs(1,INF);
            ans += res;
        }
        cout<<ans<<endl;
        // prllf("Case %d: %d
    ",cases,ans);
    }
    
    
    int main()
    {
        
        cin.sync_with_stdio(false);
        
        ll t=1 ;
        while(cin>>m>>n)init();
        // cin>>t;
        // for(ll i=0;i<t;++i)
        // {
            // cin>>m>>n;
            // init();
        // }
        // while(cin>>n>>m)init();
        
        
        return 0;
    }

      

  • 相关阅读:
    STM32时钟树
    js jQuery函数 $.ajax()
    jQuery 语法
    jQuery介绍
    python笔记2 生成器 文件读写
    python笔记1,语法,函数,类和实例,异常
    Scrapy爬虫入门系列4抓取豆瓣Top250电影数据
    Scrapy爬虫入门系列3 将抓取到的数据存入数据库与验证数据有效性
    opus 规范 与参数解析
    开源播放器ijkplayer源码结构
  • 原文地址:https://www.cnblogs.com/rikka/p/8948426.html
Copyright © 2020-2023  润新知