zoukankan      html  css  js  c++  java
  • hdu-4289 最大流Dinic模板题

    拆点,套模板。

    详情见代码。

    //
    //  main.cpp
    //  hdu_4289
    //
    //  Created by Luke on 16/8/29.
    //  Copyright © 2016年 Luke. All rights reserved.
    //
    //hdu-4289
    #include <iostream>
    #include <vector>
    #include <queue>
    #define N 500 //开两倍大小多一些
    #define INF 0x3f3f3f3f
    #define LL long long int
    using namespace std;
    int n,m;//点边
    struct Node
    {
        int to;
        LL cap;
        unsigned long rev;
    };
    LL Min(LL a,LL b)
    {
        return a>b?b:a;
    }
    vector<Node> g[N];
    int level[N];//用来存放bfs查找最短路的标号
    int itor[N];//弧优化
    void bfs(LL now)//预先进行广度优先搜索,避免dfs中大量无效查找
    {
        fill(level,level+(n<<1)+1,-1);//初始化为-1
        level[now]=0;
        queue<LL> q;
        q.push(now);
        while(!q.empty())
        {
            now=q.front(),q.pop();
            for(int i=0;i<g[now].size();i++)
            {
                Node &e=g[now][i];
                if(e.cap>0&&level[e.to]<0)
                    level[e.to]=level[now]+1,q.push(e.to);//迭代标号
            }
        }
    }
    LL dfs(LL now,LL en,LL f)
    {
        if(now==en)
            return f;
        for(int &i=itor[now];i<g[now].size();i++)//弧优化,用&迭代标号,使每次查找边跳过查找过的边
        {
            Node &e=g[now][i];
            if(e.cap>0&&level[e.to]>level[now])//如果level不满足肯定不需要查找
            {
                LL temp=dfs(e.to,en,Min(f,e.cap));
                if(temp>0)
                {
                    e.cap-=temp;
                    g[e.to][e.rev].cap+=temp;
                    return temp;
                }
            }
        }
        return 0;
    }
    void addEdge(int from,int to,LL cap)
    {
        g[from].push_back((Node){to,cap,g[to].size()});
        g[to].push_back((Node){from,0,g[from].size()-1});
    }
    void ini()
    {
        for(int i=0;i<=(n<<1)+1;i++)
            g[i].clear();
        //fill(used,used+n+1,0);
    }
    LL solve(LL s,LL en)
    {
        LL ans=0;
        while(1)
        {
            bfs(s);
            if(level[en]<0)//最短路未查找到路径,返回
                return ans;
            fill(itor,itor+(n<<1)+1,0);
            LL d;
            while((d=dfs(s,en,INF))>0)
                ans+=d;
        }
        return ans;
    }
    int main(int argc, const char * argv[]) {
        cin.sync_with_stdio(false);
        while(cin>>n>>m)
        {//本题权值在端点处,把点拆分成线段
            ini();
            LL s,e;
            int num,num2;
            cin>>s>>e;
            e+=n;
            for(int i=1;i<=n;i++)
                cin>>num,addEdge(i, i+n, num),addEdge(i+n,i,num);
            for(int i=0;i<m;i++)
                cin>>num>>num2,addEdge(num+n, num2, INF),addEdge(num2+n,num,INF);//这里反向加边时一定要注意始末位置
            cout<<solve(s,e)<<endl;
        }
        return 0;
    }
  • 相关阅读:
    连接池
    Socket编程实践(2) --Socket编程导引
    自己定义JSTL函数
    用new和delete运算符进行动态分配和撤销存储空间
    Unix网络编程学习笔记之第12章 IPv4与IPv6的互操作性
    矩阵十题【五】 VOJ1049 HDU 2371 Decode the Strings
    Unity3d / 3ds max 模型分享站点
    浙大PAT考试1077~1080(2014上机复试题目)
    Java反射学习总结五(Annotation(注解)-基础篇)
    关于http和https淘宝支付宝跨域解决方法研究
  • 原文地址:https://www.cnblogs.com/LukeStepByStep/p/5818331.html
Copyright © 2011-2022 走看看