• HDU4289 Control


      原题传送:http://acm.hdu.edu.cn/showproblem.php?pid=4289

      网络流,最大流 + 拆点。

      最大流:sap算法

      常用的两种拆点方式:

        1. 对于每个节点id,拆成 id<<1 和 id<<1|1 两个点

        2.对于每个节点id,拆成 id 和 id+n 两个点

    View Code
      1 #include <stdio.h>
      2 #include <string.h>
      3 #define L(u) ((u) << 1)
      4 #define R(u) ((u) << 1 | 1)
      5 #define N 420
      6 #define M 100000
      7 #define INF 0x3f3f3f3f
      8 
      9 int gap[N],dis[N],pre[N],cur[N];
     10 int n,m,NE, s, t;
     11 int head[N];
     12 struct Node{
     13     int c,pos,next;
     14 }E[M];
     15 
     16 inline void checkmin(int &a,int b)  {if(a == -1 || a > b)a = b;}
     17 
     18 void add_edge(int u,int v,int c)
     19 {
     20     E[NE].c = c;
     21     E[NE].pos = v;
     22     E[NE].next = head[u];   
     23     head[u] = NE++;
     24     
     25     E[NE].c = 0;    // !反向初始为0
     26     E[NE].pos = u;
     27     E[NE].next = head[v];   
     28     head[v] = NE++;
     29 }
     30 
     31 int sap()
     32 {
     33     memset(dis,0,sizeof dis);
     34     memset(gap,0,sizeof gap);
     35     memcpy (cur, head, sizeof dis);
     36     int u=pre[s]=s,maxflow=0,aug=-1;
     37     gap[0]=n;
     38     while(dis[s]<n)
     39     {
     40 loop:for(int &i=cur[u];i!=-1;i=E[i].next)
     41         {
     42             int v=E[i].pos;
     43             if(E[i].c && dis[u]==dis[v]+1)
     44             {
     45                 checkmin(aug, E[i].c);
     46                 pre[v]=u;
     47                 u=v;
     48                 if(v==t)
     49                 {
     50                     maxflow+=aug;
     51                     for(u=pre[u];v!=s;v=u,u=pre[u])
     52                     {
     53                         E[cur[u]].c-=aug;
     54                         E[cur[u]^1].c+=aug;
     55                     }
     56                     aug=-1;
     57                 }
     58                 goto loop;
     59             }
     60         }
     61         int mindis=n;
     62         for(int i=head[u];i!=-1;i=E[i].next)
     63         {
     64             int v=E[i].pos;
     65             if(E[i].c && mindis>dis[v])
     66             {
     67                 cur[u]=i;
     68                 mindis=dis[v];
     69             }
     70         }
     71         if((--gap[dis[u]])==0) break;
     72         gap[dis[u]=mindis+1]++;
     73         u=pre[u];
     74     }
     75     return maxflow;
     76 }
     77  
     78 void init()
     79 {
     80     memset(head, -1, sizeof head);
     81     NE = 0;
     82 }
     83  
     84 int main()
     85 {
     86     int i, a, b, w;
     87     while(scanf("%d%d", &n, &m) != EOF)
     88     {
     89         init();
     90         scanf("%d%d", &s, &t);
     91         add_edge(0, L(s), INF);          // 0为超级源点
     92         add_edge(R(t), R(n + 1), INF);   // R(n + 1)为超级汇点
     93         s = 0;
     94         t = R(n + 1);
     95         for(i = 1; i <= n; i ++)
     96         {
     97             scanf("%d", &w);
     98             add_edge(L(i), R(i), w);
     99             add_edge(R(i), L(i), w); 
    100         }
    101         for(i = 0; i < m; i ++)
    102         {
    103             scanf("%d%d", &a, &b);
    104             add_edge(R(a), L(b), INF);
    105             add_edge(R(b), L(a), INF);
    106         }
    107         n = 2 * (n + 1);                 // 总节点数的变化
    108         printf("%d\n", sap());
    109     }
    110     return 0;
    111 }

       

  • 相关阅读:
    MongoDB常用命令
    centos6.9下MongoDB安装
    第三十二节 selenium爬取拉勾网
    第三十节 selenium设置代理
    第三十节 selenium打开多个窗口和切换
    第二十九节 selenium隐式和显式等待
    第二十八节 selenium操作cookie信息
    第二十七节 selenium行为链
    第二十六节 selenium操作表单元素
    SpringMVC工作原理详解
  • 原文地址:https://www.cnblogs.com/huangfeihome/p/2694519.html
Copyright © 2020-2023  润新知