USACO Section 4.2 Drainage Ditches - 复习网络流



     回顾了下网络流~~本题就是赤果果的最大流~~~话说开始写裸的爆搜增广路超时了~~用了dinic才过的~~庆幸过了好几个月了还能马上把最大流写出来~~


Program:

/*  
ID: zzyzzy12   
LANG: C++   
TASK: ditch
*/      
#include<iostream>      
#include<istream>  
#include<stdio.h>      
#include<string.h>      
#include<math.h>      
#include<stack>
#include<map>
#include<algorithm>      
#include<queue>   
#define oo 2000000000  
#define ll long long  
#define pi (atan(2)+atan(0.5))*2 
using namespace std;
struct node
{
      int x,y,c,next;      
}line[1001];
int n,m,_link[501],way[501],dep,MaxFlow,x,MinFlow,dis[501];
bool used[501],f;
queue<int> myqueue;
void EK(int p)
{
      int k;       
      if (p==n)
      {
             MinFlow=oo;  
             for (k=dep;k>=1;k--)
             if (line[way[k]].c<=MinFlow)
             {
                    MinFlow=line[way[k]].c;
                    x=line[way[k]].x-1;                     
             }  
             for (k=1;k<=dep;k++)  
             { 
                    m++;
                    line[m].x=line[way[k]].y; 
                    line[m].y=line[way[k]].x;
                    line[m].c=MinFlow;
                    line[m].next=_link[line[m].x]; _link[line[m].x]=m;                    
                    line[way[k]].c-=MinFlow; 
             }
             MaxFlow+=MinFlow; 
             f=true;
             return;         
      }  
      used[p]=true;  
      k=_link[p];
      while (k)
      {
             if (!used[line[k].y] && line[k].c && dis[line[k].y]-dis[line[k].x]==1)
             {
                    way[++dep]=k;              
                    EK(line[k].y);
                    dep--; 
                    if (x)
                      if (x!=p) return;
                       else x=0;
             }
             k=line[k].next;
      }
      used[p]=false; 
      return;       
} 
void BFS()
{
      int i,k,h;
      for (i=1;i<=n;i++) dis[i]=oo;
      while (!myqueue.empty()) myqueue.pop();
      memset(used,false,sizeof(used));
      myqueue.push(1); dis[1]=0;
      while (!myqueue.empty())
      {
             h=myqueue.front();
             myqueue.pop(); 
             k=_link[h];
             while (k)
             {
                   if (line[k].c && dis[line[k].y]>dis[h]+1)
                   {
                          dis[line[k].y]=dis[h]+1;
                          if (!used[line[k].y])
                          {
                                used[line[k].y]=true;  
                                myqueue.push(line[k].y);                   
                          }                      
                   }                 
                   k=line[k].next;  
             }
      }     
}
int main()  
{  
      freopen("ditch.in","r",stdin);   
      freopen("ditch.out","w",stdout);
      scanf("%d%d",&m,&n);
      memset(_link,0,sizeof(_link));
      int i,k,h;
      for (i=1;i<=m;i++)
      {
            scanf("%d%d%d",&line[i].x,&line[i].y,&line[i].c);
            line[i].next=_link[line[i].x]; _link[line[i].x]=i;            
      }   
      MaxFlow=0;
      if (n>1) 
      while (1)
      {
            BFS(); 
            f=false;
            memset(used,false,sizeof(used));
            x=0; dep=0;
            EK(1);
            if (!f) break;
      }
      printf("%d\n",MaxFlow);
      return 0;     
}   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值