zoukankan      html  css  js  c++  java
  • 网络流之最大流 poj 1459

    差不多三天的时间过去了,学了一个网络流最大流。。

    现在来总结一下。。。

    先说一下之前那个ek的算法,说实话,这个算法本质上很好去理解,就是利用一个广搜不断的搜出所谓的增广路径。

    View Code
     1 #include<iostream>
     2     #include<string.h>
     3     #include<queue>
     4     #define N 110
     5     using namespace std;
     6     int map[N][N];
     7     int n,np,nc,m,s,e,w; 
     8     int link[N],num[N],answer;
     9     char temp[20];
    10     int bfs()
    11     {
    12         queue<int> q;
    13         num[n]=0x7fffffff;
    14         q.push(n);
    15         for(int i=0;i<=n+1;i++)link[i]=-1;
    16         while(!q.empty())
    17         {
    18             int cur=q.front();
    19             q.pop();
    20             if(cur==n+1)
    21             {
    22                answer+=num[n+1];
    23                int from,now=n+1;
    24                while(now!=n)
    25                {
    26                    from=link[now];
    27                    map[from][now]-=num[n+1];
    28                    map[now][from]+=num[n+1];
    29                    now=from;
    30                }
    31                while(!q.empty())q.pop();
    32                num[n]=0x7fffffff;
    33                for(int i=0;i<=n+1;i++)link[i]=-1;
    34                q.push(n);
    35                continue;
    36             }
    37             for(int i=0;i<=n+1;i++)
    38             {
    39                if(map[cur][i]&&link[i]==-1)
    40                {
    41                    link[i]=cur;
    42                    num[i]=num[cur]<map[cur][i]?num[cur]:map[cur][i];
    43                    q.push(i);
    44                }
    45             }
    46         }
    47         return answer;  
    48     }
    49     int main()
    50     {
    51        while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF)
    52        {
    53               for(int i=0;i<=n+1;i++)
    54               {
    55                  for(int j=0;j<=n+1;j++)
    56                  {
    57                          map[i][j]=0;
    58                  }
    59               }
    60               while(m--)
    61               {
    62                  getchar();
    63                  scanf("%s",temp);
    64                  int i=1,len=strlen(temp);
    65                  s=e=w=0;
    66                  while(temp[i]!=','){s=s*10+temp[i]-'0';i++;}
    67                  i++;
    68                  while(temp[i]!=')'){e=e*10+temp[i]-'0';i++;}
    69                  i++;
    70                  while(i<len){w=w*10+temp[i]-'0';i++;}
    71                  map[s][e]+=w;
    72               }
    73               while(np--)
    74               {
    75                  scanf("%s",temp);
    76                  int i=1,len=strlen(temp);
    77                  s=w=0;
    78                  while(temp[i]!=')'){s=s*10+temp[i]-'0';i++;}
    79                  i++;
    80                  while(i<len){w=w*10+temp[i]-'0';i++;}
    81                  map[n][s]+=w;
    82               }
    83               while(nc--)
    84               {
    85                  scanf("%s",temp);
    86                  int i=1,len=strlen(temp);
    87                  s=w=0;
    88                  while(temp[i]!=')'){s=s*10+temp[i]-'0';i++;}
    89                  i++;
    90                  while(i<len){w=w*10+temp[i]-'0';i++;}
    91                  map[s][n+1]+=w;
    92               }
    93               answer=0;
    94               printf("%d\n",bfs());
    95        }
    96        return 0;
    97     }

    虽然这个算法比较好理解,但是在时间上面确实是十分的底下的。。

    所以开始了sap的学习,现在设置一个距离标号为dis[i],表示i节点和终点的距离。首先先全部初始化为0,然后若现在有一条路径k->t->终点,则表示dis[k]=dis[t]+1;ok了,说了这个,说实话应该会看的比较懂的。。

    不过下面有两种样式的代码,一个是递归的,比较好理解,而非递归的就是在模拟递归一样,不要被代码长度吓到,不过说实话,我那个时候还是被吓到了的…

    View Code
     1 #include<iostream>
     2 #define min(a,b) a<b?a:b
     3 #define Inf 0x7fffffff
     4 #define N 110
     5 using namespace std;
     6 int n,np,nc,m,map[N][N],dis[N],gap[N];
     7 int s,e,w;//起点、终点、权值 
     8 char temp[20];
     9 int dfs(int src,int aug)
    10 {
    11      if(src==n+1)return aug;
    12      int flow=0,min_d=n+1;
    13      for(int i=0;i<=n+1;i++)
    14      {
    15          if(map[src][i])
    16          {
    17              if(dis[src]==dis[i]+1)
    18              {
    19                  int t=dfs(i,min(aug-flow,map[src][i]));
    20                  map[src][i]-=t;
    21                  map[i][src]+=t;
    22                  flow+=t;
    23                  if(aug==flow)break;
    24              }
    25              min_d=min(min_d,dis[i]);
    26          }
    27      }
    28      if(!flow)
    29      {
    30          if(!(gap[dis[src]]--))dis[n]=n+2;
    31          ++gap[dis[src]=min_d+1];
    32      }
    33      return flow; 
    34 }
    35 int main()
    36 {
    37     while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF)
    38     {
    39          for(int i=0;i<=n+1;i++)
    40              for(int j=0;j<=n+1;j++)
    41                 map[i][j]=0;
    42          while(m--)
    43          {
    44                 scanf("%s",temp);
    45                 int i=1,len=strlen(temp);
    46                 s=e=w=0;
    47                 while(temp[i]!=','){s=s*10+temp[i]-'0';i++;}i++;
    48                 while(temp[i]!=')'){e=e*10+temp[i]-'0';i++;}i++;
    49                 while(i<len){w=w*10+temp[i]-'0';i++;}
    50                 map[s][e]+=w;
    51          }
    52          while(np--)
    53          {
    54                 scanf("%s",temp);
    55                 int i=1,len=strlen(temp);
    56                 s=w=0;
    57                 while(temp[i]!=')'){s=s*10+temp[i]-'0';i++;}i++;
    58                 while(i<len){w=w*10+temp[i]-'0';i++;}
    59                 map[n][s]+=w;
    60          }
    61          while(nc--)
    62          {
    63                 scanf("%s",temp);
    64                 int i=1,len=strlen(temp);
    65                 s=w=0;
    66                 while(temp[i]!=')'){s=s*10+temp[i]-'0';i++;}i++;
    67                 while(i<len){w=w*10+temp[i]-'0';i++;}
    68                 map[s][n+1]=w;
    69          }
    70          int answer=0;
    71          for(int i=0;i<=n+1;i++)dis[i]=gap[i]=0;
    72          gap[0]=n+1;
    73          while(dis[n]<=n+1)answer+=dfs(n,Inf);
    74          printf("%d\n",answer);
    75     }
    76     return 0;   
    77 }
    View Code
      1 #include<iostream>
      2 #define min(a,b) a<b?a:b
      3 #define Inf 0x7fffffff
      4 #define N 110
      5 using namespace std;
      6 int n,np,nc,m,map[N][N],dis[N],gap[N],answer;
      7 int s,e,w;//起点、终点、权值 
      8 int back_flow[N],cur_arc[N],pre[N],neck[N];
      9 char temp[20];
     10 void bfs()
     11 {
     12     int cur_flow,flag,min_dis,temp,cur;
     13     cur=n;
     14     cur_flow=Inf;
     15     neck[n]=n;
     16     while(dis[n]<=n+1)
     17     {
     18          back_flow[cur]=cur_flow;
     19          flag=0;
     20          for(int i=cur_arc[cur];i<=n+1;i++)
     21          {
     22              if(map[cur][i]&&dis[cur]==dis[i]+1)
     23              {   
     24                  pre[i]=cur;
     25                  cur_arc[cur]=i;
     26                  flag=1;
     27                  if(map[cur][i]<cur_flow)
     28                  {
     29                      cur_flow=map[cur][i];
     30                      neck[i]=cur; 
     31                  }
     32                  else
     33                  {
     34                      neck[i]=neck[cur]; 
     35                  }          
     36                  cur=i;
     37                  if(cur==n+1)
     38                  {
     39                      answer+=cur_flow;
     40                      while(cur!=n)
     41                      {
     42                          map[pre[cur]][cur]-=cur_flow;
     43                          back_flow[cur]-=cur_flow;
     44                          map[cur][pre[cur]]+=cur_flow;
     45                          cur=pre[cur]; 
     46                      }            
     47                      cur=neck[cur];
     48                      cur_flow=back_flow[cur]; 
     49                  }
     50                  break;
     51              }
     52          }
     53          if(flag)continue;
     54          min_dis=n+1;
     55          for(int i=0;i<=n+1;i++)
     56          {
     57              if(map[cur][i]&&dis[i]<min_dis)
     58              {
     59                min_dis=dis[i];
     60                temp=i;
     61              }
     62          }
     63          cur_arc[cur]=temp;
     64          gap[dis[cur]]--;
     65          if(gap[dis[cur]]==0)break;
     66          dis[cur]=min_dis+1;
     67          gap[dis[cur]]++;
     68          if(cur!=n)
     69          {
     70             cur=pre[cur];
     71             cur_flow=back_flow[cur];
     72          }
     73     }
     74 }
     75 int main()
     76 {
     77     while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF)
     78     {
     79          for(int i=0;i<=n+1;i++)
     80              for(int j=0;j<=n+1;j++)
     81                 map[i][j]=0;
     82          while(m--)
     83          {
     84                 scanf("%s",temp);
     85                 int i=1,len=strlen(temp);
     86                 s=e=w=0;
     87                 while(temp[i]!=','){s=s*10+temp[i]-'0';i++;}i++;
     88                 while(temp[i]!=')'){e=e*10+temp[i]-'0';i++;}i++;
     89                 while(i<len){w=w*10+temp[i]-'0';i++;}
     90                 map[s][e]+=w;
     91          }
     92          while(np--)
     93          {
     94                 scanf("%s",temp);
     95                 int i=1,len=strlen(temp);
     96                 s=w=0;
     97                 while(temp[i]!=')'){s=s*10+temp[i]-'0';i++;}i++;
     98                 while(i<len){w=w*10+temp[i]-'0';i++;}
     99                 map[n][s]+=w;
    100          }
    101          while(nc--)
    102          {
    103                 scanf("%s",temp);
    104                 int i=1,len=strlen(temp);
    105                 s=w=0;
    106                 while(temp[i]!=')'){s=s*10+temp[i]-'0';i++;}i++;
    107                 while(i<len){w=w*10+temp[i]-'0';i++;}
    108                 map[s][n+1]=w;
    109          }
    110          answer=0;
    111          for(int i=0;i<=n+1;i++)cur_arc[i]=dis[i]=gap[i]=0;
    112          gap[0]=n+2;
    113          bfs();
    114          printf("%d\n",answer);
    115     }
    116     return 0;   
    117 }
  • 相关阅读:
    Android防止按钮连续点击
    Android中的AlertDialog遇到的错误
    android通过Jni加载so库遇到UnsatisfiedLinkError问题!!!
    接口回调
    Android中的APinner2
    AndroidAPI
    Android中的下拉列表
    学习地址
    2018/12/21:Date类
    2018/12.21:找出数组最大项和最小项。
  • 原文地址:https://www.cnblogs.com/nuoyan2010/p/2670516.html
Copyright © 2011-2022 走看看