zoukankan      html  css  js  c++  java
  • dinic模板

    
    
     procedure addedge(u,v,cap:longint);
       begin
         sid[tot].u:=u;
         sid[tot].v:=v;
         sid[tot].cap:=cap;
         sid[tot].next:=nd[u];
         nd[u]:=tot;
         inc(tot);
         sid[tot].u:=v;
         sid[tot].v:=u;
         sid[tot].cap:=0;
         sid[tot].next:=nd[v];
         nd[v]:=tot;
         inc(tot);
       end;

     function bfs:boolean;
     var
      i,head,tail,u,p:longint;
       begin
         for i:=0 to n*m+1 do
           dep[i]:=-1;
         dep[0]:=0;
         head:=1;tail:=1;dl[1]:=0;
         while head<=tail do
           begin
             u:=dl[head];
             p:=nd[dl[head]];
             while p<>-1 do
               begin
                 if (sid[p].cap>0) and (dep[sid[p].v]=-1) then
                   begin
                     dep[sid[p].v]:=dep[u]+1;
                     if sid[p].v=n*m+1 then exit(true);
                     inc(tail);
                     dl[tail]:=sid[p].v;
                   end;
                 p:=sid[p].next;
               end;
             inc(head);
           end;
         exit(false);
       end;
    
     function dinic:longint;
     var
      top,i,u,mi,last:longint;
       begin
         dinic:=0;
         while bfs do
           begin
             fillchar(stack,sizeof(stack),0);
             top:=0;
             for i:=0 to n*m+1 do cur[i]:=nd[i];
             u:=0;
             while true do
               begin
                 if u=n*m+1 then
                   begin
    
                     mi:=maxlongint;
                     for i:=1 to top do
                       begin
                         if sid[stack[i]].cap<mi then
                           begin
                             last:=i;
                             mi:=sid[stack[i]].cap;
                           end;
                       end;
    
                     for i:=1 to top do
                       begin
                         dec(sid[stack[i]].cap,mi);
                         inc(sid[stack[i] xor 1].cap,mi);
                       end;
    
                     top:=last-1;
                     dinic:=dinic+mi;
                     u:=sid[stack[last]].u;
                   end;
    
                  while cur[u]<>-1 do
                    begin
                      if (dep[sid[cur[u]].v]=dep[u]+1) and (sid[cur[u]].cap<>0) then break
                      else  cur[u]:=sid[cur[u]].next;
                    end;
    
                 if cur[u]=-1 then
                   begin
                     if u=0 then break;
                     dep[u]:=-1;
                     u:=sid[stack[top]].u;
                     dec(top);
                   end else
                   begin
                     inc(top);
                     stack[top]:=cur[u];
                     u:=sid[cur[u]].v;
                   end;
               end;
           end;
       end;
     

     最大流=最小割=正点权和-最大闭合权图

    其中求最大闭合权图时,源点向所有点权为正的点连容量为点权的边,所有点权为负的点向汇点连容量为点权绝对值的边

    表示约束关系的边容量为无穷大,i前必须做j,i连向j

    -----------------------------------------------------------------------------------------------

       
      void addedge2(int u,int v,int cap){
          sid[cnt].next=nd[u];sid[cnt].des=v;sid[cnt].cap=cap;nd[u]=cnt;sid[cnt].fr=u;cnt++;
          sid[cnt].next=nd[v];sid[cnt].des=u;sid[cnt].cap=0;nd[v]=cnt;sid[cnt].fr=v;cnt++;
      }
       
       int bfs(){
          memset(dep,-1,sizeof(dep));
          
          int head=1,tail=1;
          dep[sor]=0;dl[head]=sor;
          while (head<=tail){
            for (int p=nd[dl[head]];p!=-1;p=sid[p].next)
              if ((dep[sid[p].des]==-1)&&(sid[p].cap)) dep[sid[p].des]=dep[dl[head]]+1,dl[++tail]=sid[p].des;
            head++;  
        }
        
        if (dep[tar]==-1) return(0);else return(1);
      }
      
      int dinic(){
          int maxflow=0;
          while (bfs()){
              for (int i=0;i<=tar;i++) cur[i]=nd[i];
              
              int u=sor,top=0;
    while(1){
                  if (u==tar){
                      int mi=1e9,last;
                      for (int i=1;i<=top;i++)
                        if (sid[sta[i]].cap<mi)
                        {mi=sid[sta[i]].cap;last=i;}
                        
                      for (int i=1;i<=top;i++) 
                      sid[sta[i]].cap-=mi,sid[sta[i]^1].cap+=mi;
                    u=sid[sta[last]].fr;cur[u]=sid[cur[u]].next;top=last-1;
                    maxflow+=mi;
                    continue;
                }
                
                while((cur[u]!=-1)&&((sid[cur[u]].cap==0)||(dep[sid[cur[u]].des]!=dep[u]+1)))
                  cur[u]=sid[cur[u]].next;
                  
                if (cur[u]!=-1){sta[++top]=cur[u];u=sid[cur[u]].des;continue;}
                else{
                    if (u==sor) break;
                    dep[u]=-1;
                    u=sid[sta[top--]].fr;
                    continue;
                }       
              }
          }
          return(maxflow);
      }
     
  • 相关阅读:
    UI自动化测试(二)浏览器操作及对元素的定位方法(xpath定位和css定位详解)
    UI自动化测试(一)简介及Selenium工具的介绍和环境搭建
    接口测试——HttpClient工具的https请求、代理设置、请求头设置、获取状态码和响应头
    SpringBoot系列之JDBC数据访问
    Docker系列之MySQL安装教程
    Docker系列之常用命令操作手册
    Docker系列之原理简单介绍
    SpringBoot系列之集成jsp模板引擎
    SpringBoot源码学习系列之嵌入式Servlet容器
    SpringBoot源码学习系列之异常处理自动配置
  • 原文地址:https://www.cnblogs.com/zhujiangning/p/5231074.html
Copyright © 2011-2022 走看看